⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mexcdf53.c

📁 MATLAB中读写、处理科学数据文件格式NETCDF的程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 *	mexcdf53.c -- For Matlab Version 5 and NetCDF Version 3.
 *
 *	******************** NOTICE ********************
 *
 *	MEXCDF53 -- USGS Preliminary Computer Software For
 *		Interaction Between Matlab-5 and NetCDF-3.
 *
 *	Begun:		Tuesday, July 14, 1992 6:59:54 PM.
 *	Version:	Tuesday, March 4, 1997 3:54:00 PM.
 *	Version:	Wednesday, December 16, 1998 4:43:00 PM.
 *					byte ==> (signed char) Jim Mansbridge.
 *	Version:	Monday, January 24, 2000 19:11:50 PM.
 *					varget1, vargetg, attget: plhs[0]
 *  Version:    Tuesday, September 17, 2002.
 *                  MacOSX version built with this.
 *
 *	Written, Maintained, and Supported By:
 *		Dr. Charles R. Denham
 *		U.S. Geological Survey
 *		Woods Hole, Massachusetts 02543
 *		e-mail: cdenham@usgs.gov
 *
 *	Computer Programming Language:
 *		The C-Language.
 *
 *	Computer System:
 *		This software has been successfully linked with
 *		the NetCDF-3 library and executed from Matlab-5
 *		on Power Macintosh and DEC Alpha hardware.  The
 *		software is intended to be compatible with all
 *		installations of Matlab-4, Matlab-5, NetCDF-2,
 *		and NetCDF-3.
 *
 *	Source Code Available From:
 *		Author.
 *
 *	Disclaimer:
 *		Although this software has been used by the USGS, no
 *		warranty, expressed or implied, is made by the USGS
 *		or the United States Government as to the accuracy
 *		and functioning of the software and related software
 *		material, nor shall the fact of distribution constitute
 *		any such warranty or publication, and no responsibility
 *		is assumed by the USGS in connection therewith.
 *
 *	Fair Use:
 *		This software, named "mexcdf53", may be used freely on
 *		condition that this NOTICE be displayed prominantly and
 *		in its entirety on all copies of the software, as well
 *		as on all copies of software that has been derived from
 *		this software.  Furthermore, this software requires the
 *		UCAR/Unidata NetCDF library, whose conditions on proper
 *		credit, distribution, and use must be acknowledged and
 *		honored fully.
 *
 *	******************** END OF NOTICE ********************
 *
 *	Use mexcdf53.c and mexcdf.h, plus a valid NetCDF library,
 *	to build mexcdf53.mex, a mex-file function that is intended
 *	to be executed from Matlab.
 *
 *	This source-code uses MATLAB Version 5 mex-file syntax,
 *	but it still requires that the -V4 compiler-flag be
 *	specified when building with the "mex" script supplied
 *	by MathWorks.  (V4 not relevant with Matlab 6.)
 *
 *	The strictly two-dimensional assumption of Matlab-4 can
 *	be recreated by specifying the MEXCDF_4 compiler-flag,
 *	in addition to the -V4 flag mentioned above.
 *  (V4 not relevant with Matlab 6.)
 *
 *	To build mexcdf53 for use with MATLAB Version 4, specify
 *	the MEXCDF_4 flag, as well as other flags required by
 *	the "cmex" script supplied previously by MathWorks.
 *
 *	This Mex-file invokes the high-level C-Language NetCDF-2
 *	interface of the NetCDF Users Guide.  All of the specified
 *	NetCDF input arguments are required.  All output arguments
 *	are optional.
 *
 *	Matlab Syntax:
 *
 *		[out1, out2, ...] = mexcdf53('operation', in1, in2, ...)
 *
 *	Extensions:
 *
 *		1.	Dimensions and variables accessible by id or name.
 *		2.	Attributes accessible by name or number.
 *		3.	Parameters accessible by number or name.
 *		4.	Prepended "nc" not necessary for operation names.
 *		5.	Prepended "NC_" not necessary for specifying parameters.
 *		6.	Parameter names not case-sensitive.
 *		7.	Required lengths default to actual lengths via -1.
 *		8.	Scaling via "scale_factor" and "add_offset" attributes.
 *		9.	SETOPTS to set NetCDF options.  NC_FATAL is disabled.
 *		10.	ERR to get and auto-reset the most recent error-code.
 *		11.	PARAMETER to access parameters by name.
 *		12.	USAGE to list mexcdf53 syntax.
 *
 */

# include <ctype.h>
# include <errno.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>

# include "netcdf.h"

# include "mex.h"

# include "mexcdf.h"

static	VOID			Usage			(VOID);

static	Matrix		*	SetNum			(Matrix *);
static	Matrix		*	SetStr			(Matrix *);

static	char		*	Mat2Str			(Matrix *);
static	Matrix		*	Str2Mat			(char *);

static	int			*	Mat2Int			(Matrix *);
static	Matrix		*	Int2Mat			(int *, int, int);

static	long		*	Mat2Long		(Matrix *);
static	Matrix		*	Long2Mat		(long *, int, int);

static	int				Scalar2Int		(Matrix *);
static	Matrix		*	Int2Scalar		(int);

static	long			Scalar2Long		(Matrix *);
static	Matrix		*	Long2Scalar		(long);

static	int				Count			(Matrix *);

static	int				Parameter		(Matrix *);

static	VOID			Free			(VOIDPP);

static	DOUBLE			Scale_Factor	(int, int);
static	DOUBLE			Add_Offset		(int, int);

static	int				Convert			(OPCODE, nc_type, int, VOIDP,
											DOUBLE, DOUBLE, DOUBLE *);

static	nc_type			RepairBadDataType	(nc_type);


/*	MexFunction(): Mex-file entry point.	*/

void
mexFunction	(
	INT			nlhs,
	Matrix	*	plhs[],
	INT			nrhs,
	const Matrix	*	prhs[]
	)

{
	char		*	opname;
	OPCODE			opcode;
	
	Matrix		*	mat;
	
	int				status;
	char		*	path;
	int				cmode;
	int				mode;
	int				cdfid;
	int				ndims;
	int				nvars;
	int				natts;
	int				recdim;
	char		*	name;
	long			length;
	int				dimid;
	nc_type			datatype;
	int			*	dim;
	int				varid;
	long		*	coords;
	VOIDP			value;
	long		*	start;
	long		*	count;
	int			*	intcount;
	long		*	stride;
	long		*	imap;
	long			recnum;
	int				nrecvars;
	int			*	recvarids;
	long		*	recsizes;
	VOIDPP			datap;		/*	pointers for record access.	*/
	int				len;
	int				incdf;
	int				invar;
	int				outcdf;
	int				outvar;
	int				attnum;
	char		*	attname;
	char		*	newname;
	int				fillmode;
	
	int				i;
	int				m;
	int				n;
	char		*	p;
	char			buffer[MAX_BUFFER];
	
	DOUBLE		*	pr;
	DOUBLE			addoffset;
	DOUBLE			scalefactor;
	int				autoscale;		/*	do auto-scaling if this flag is non-zero.	*/
	
	/*	Disable the NC_FATAL option from ncopts.	*/
	
	if (ncopts & NC_FATAL)	{
		ncopts -= NC_FATAL;
	}
	
	/*	Display usage if less than one input argument.	*/
	
	if (nrhs < 1)	{
	
		Usage();
		
		return;
	}
	
	/*	Convert the operation name to its opcode.	*/
	
	opname = Mat2Str(prhs[0]);
	for (i = 0; i < strlen(opname); i++)	{
		opname[i] = (char) tolower((int) opname[i]);
	}
	p = opname;
	if (strncmp(p, "nc", 2) == 0)	{	/*	Trim away "nc".	*/
		p += 2;
	}
	
	i = 0;
	opcode = NONE;
	while (ops[i].opcode != NONE)	{
		if (!strcmp(p, ops[i].opname))	{
			opcode = ops[i].opcode;
			if (ops[i].nrhs > nrhs)	{
				mexPrintf("MEXCDF: opname = %s\n", opname);
				mexErrMsgTxt("MEXCDF: Too few input arguments.\n");
			}
			else if (0 && ops[i].nlhs > nlhs)	{	/*	Disabled.	*/
				mexPrintf("MEXCDF: opname = %s\n", opname);
				mexErrMsgTxt("MEXCDF: Too few output arguments.\n");
			}
			break;
		}
		else	{
			i++;
		}
	}
	
	if (opcode == NONE)	{
		mexPrintf("MEXCDF: opname = %s\n", opname);
		mexErrMsgTxt("MEXCDF: No such operation.\n");
	}
	
	Free((VOIDPP) & opname);
	
	/*	Extract the cdfid by number.	*/
	
	switch (opcode)	{
	
	case USAGE:
	case CREATE:
	case OPEN:
	case TYPELEN:
	case SETOPTS:
	case ERR:
	case PARAMETER:
	
		break;
	
	default:

		cdfid = Scalar2Int(prhs[1]);
	
		break;
	}
	
	/*	Extract the dimid by number or name.	*/
	
	switch (opcode)	{

	case DIMINQ:
	case DIMRENAME:
	
		if (mxIsNumeric(prhs[2]))	{
			dimid = Scalar2Int(prhs[2]);
		}
		else	{
			name = Mat2Str(prhs[2]);
			dimid = ncdimid(cdfid, name);
			Free((VOIDPP) & name);
		}
		break;
	
	default:
	
		break;
	}
	
	/*	Extract the varid by number or name.	*/
	
	switch (opcode)	{

	case VARINQ:
	case VARPUT1:
	case VARGET1:
	case VARPUT:
	case VARGET:
	case VARPUTG:
	case VARGETG:
	case VARRENAME:
	case VARCOPY:
	case ATTPUT:
	case ATTINQ:
	case ATTGET:
	case ATTCOPY:
	case ATTNAME:
	case ATTRENAME:
	case ATTDEL:
	
		if (mxIsNumeric(prhs[2]))	{
			varid = Scalar2Int(prhs[2]);
		}
		else	{
			name = Mat2Str(prhs[2]);
			varid = ncvarid(cdfid, name);
			Free((VOIDPP) & name);
			if (varid == -1)	{
				varid = Parameter(prhs[2]);
			}
		}
		break;
	
	default:
	
		break;
	}
	
	/*	Extract the attname by name or number.	*/
	
	switch (opcode)	{
	
	case ATTPUT:
	case ATTINQ:
	case ATTGET:
	case ATTCOPY:
	case ATTRENAME:
	case ATTDEL:
	
		if (mxIsNumeric(prhs[3]))	{
			attnum = Scalar2Int(prhs[3]);
			attname = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
			status = ncattname(cdfid, varid, attnum, attname);
		}
		else	{
			attname = Mat2Str(prhs[3]);
		}
		break;
	
	default:
	
		break;
	}
	
	/*	Extract the "add_offset" and "scale_factor" attributes.	*/
	
	switch (opcode)	{
	
	case VARPUT1:
	case VARGET1:
	case VARPUT:
	case VARGET:
	case VARPUTG:
	case VARGETG:

		addoffset = Add_Offset(cdfid, varid);
		scalefactor = Scale_Factor(cdfid, varid);
		if (scalefactor == 0.0)	{
			scalefactor = 1.0;
		}
		
		break;
	
	default:
	
		break;
	}
	
	/*	Perform the NetCDF operation.	*/
	
	switch (opcode)	{
		
	case USAGE:
	
		Usage();
		
		break;
	
	case CREATE:
		
		path = Mat2Str(prhs[1]);
		
		if (nrhs > 2)	{
			cmode = Parameter(prhs[2]);
		}
		else	{
			cmode = NC_NOCLOBBER;	/*	Default.	*/
		}
		
		cdfid = nccreate(path, cmode);
		
		plhs[0] = Int2Scalar(cdfid);
		plhs[1] = Int2Scalar((cdfid >= 0) ? 0 : -1);
		
		Free((VOIDPP) & path);
		
		break;
		
	case OPEN:
		
		path = Mat2Str(prhs[1]);
		
		if (nrhs > 2)	{
			mode = Parameter(prhs[2]);
		}
		else	{
			mode = NC_NOWRITE;	/*	Default.	*/
		}
		
		cdfid = ncopen(path, mode);
		
		plhs[0] = Int2Scalar(cdfid);
		plhs[1] = Int2Scalar((cdfid >= 0) ? 0 : -1);
		
		Free((VOIDPP) & path);
		
		break;
		
	case REDEF:
		
		status = ncredef(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case ENDEF:
		
		status = ncendef(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case CLOSE:
		
		status = ncclose(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case INQUIRE:
	
		status = ncinquire(cdfid, & ndims, & nvars, & natts, & recdim);
		
		if (nlhs > 1)	{
			plhs[0] = Int2Scalar(ndims);
			plhs[1] = Int2Scalar(nvars);
			plhs[2] = Int2Scalar(natts);
			plhs[3] = Int2Scalar(recdim);
			plhs[4] = Int2Scalar(status);
		}
		else	{	/*	Default to 1 x 5 row vector.	*/
			plhs[0] = mxCreateFull(1, 5, REAL);
			pr = mxGetPr(plhs[0]);
			if (status == 0)	{
				pr[0] = (DOUBLE) ndims;
				pr[1] = (DOUBLE) nvars;
				pr[2] = (DOUBLE) natts;
				pr[3] = (DOUBLE) recdim;
			}
			pr[4] = (DOUBLE) status;
		}
		
		break;
		
	case SYNC:
	
		status = ncsync(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case ABORT:
	
		status = ncabort(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case DIMDEF:
	
		name = Mat2Str(prhs[2]);
		length = Parameter(prhs[3]);
		
		dimid = ncdimdef(cdfid, name, length);
		
		plhs[0] = Int2Scalar(dimid);
		plhs[1] = Int2Scalar((dimid >= 0) ? 0 : dimid);
		
		Free((VOIDPP) & name);
		
		break;
		
	case DIMID:
	
		name = Mat2Str(prhs[2]);
		
		dimid = ncdimid(cdfid, name);
		
		plhs[0] = Int2Scalar(dimid);
		plhs[1] = Int2Scalar((dimid >= 0) ? 0 : dimid);
		
		Free((VOIDPP) & name);
		
		break;
		
	case DIMINQ:
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		
		status = ncdiminq(cdfid, dimid, name, & length);
		
		plhs[0] = Str2Mat(name);
		plhs[1] = Long2Scalar(length);
		plhs[2] = Int2Scalar(status);
		
		Free((VOIDPP) & name);
		
		break;
		
	case DIMRENAME:
		
		name = Mat2Str(prhs[3]);
		
		status = ncdimrename(cdfid, dimid, name);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & name);
		
		break;
		
	case VARDEF:
	
		name = Mat2Str(prhs[2]);
		datatype = (nc_type) Parameter(prhs[3]);
		ndims = Scalar2Int(prhs[4]);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -