利用fortran创建、读取、写netCDF(.nc)的教程
- 格式:pdf
- 大小:51.01 KB
- 文档页数:14
N etCDF 数据的编程式访问查石祥(总参气象中心,北京100081)作者简介:查石祥,男,1965年生,硕士,高级工程师,从事数值预报模式与高性能计算研究,Email :sxzha @ 收稿日期:2004年6月12日;定稿日期:2004年9月1日摘要 NetCDF 是一种面向数组型数据的描述和编码标准,目前广泛应用于大气科学、水文、海洋学、环境模拟、地球物理等诸多领域。
用户可以借助多种方式方便地管理和操作NetCDF 数据集。
文章介绍NetCDF 数据的编程式访问方法。
该方法主要应用于数值预报模式,它涉及软件创建、参数配置、NetCDF 文件结构、NetCDF 接口函数库等。
重点探讨了编程者在使用该方法时经常遇到的一些问题,并且给出了一个读取NCEP 再分析文件的编程实例。
关键词 NetCDF 编程环境 文件结构 接口函数库引言NetCDF 是一种面向数组型数据的描述和编码标准,已被国内外许多行业和组织采用,目前广泛应用于大气科学、水文、海洋学、环境模拟、地球物理等诸多领域。
例如,NCEP (美国国家环境预报中心)发布的再分析资料,NOAA CDC (气候数据中心)发布的海洋与大气综合数据集(COADS )均采用NetCDF 作为标准。
本文介绍NetCDF 数据的编程式访问———通过调用NetCDF 软件包提供的库函数,以编程方式实现对NetCDF 数据的直接读写。
这种方式更多地应用于数值预报模式中,作为模式I/O 模块的一部分,实现对NetCDF 数据的直接读写,例如,目前在气象和海洋领域应用较广泛的WRF 模式[1]、POM 模式、LASG 的气候模式等都包含这样的功能选项。
由于NetCDF 软件秉承OSF (Open Software Foun 2dation )理念,在采用编程方式访问NetCDF 数据时,涉及编程环境的创建、NetCDF 文件结构、NetCDF 接口函数库等。
笔者以自己的开发经验,在综合大量相关网络资源的基础之上,除了简要介绍NetCDF 之外,有针对性地探讨了编程者在使用该方法时常会遇到的一些问题,并且给出了一个读取NCEP 再分析文件的编程实例,希望对同行有所助益。
第3章顺序结构设计本章介绍数据输入/输出语句及其他基本语句,简单介绍顺序结构及程序设计的基本步骤,书写简单程序。
3.1 变量的赋值变量代表计算机内存中的存储单元,它可以接收外部设备输入的数据,也可保留运算器的运算结果,还可以被送到外部设备输出。
FORTRAN语言要求变量必须被预先赋值,然后才能被使用,并提供了下面几种为变量赋值的方式,因此,程序中的变量都应该在使用之前用下列方式之一获得数据。
3.1.1 赋值语句1)赋值语句的格式和功能语句的格式:变量 = 表达式语句的功能:将一个表达式的计算结果值赋给一个变量。
关于赋值语句的说明:(1)赋值语句是执行语句。
(2)赋值语句中的“=”号叫做“赋值号”,它的作用是将其右边的表达式的结果赋给其左边的变量,即将表达式的值放入变量对应的内存单元中,因此,赋值号的意义是带有方向性和动作性的。
例如“A=5.5”的作用是将5.5 送到变量A对应的内存单元中。
(3)赋值语句兼有计算和赋值双重功能。
即先计算出表达式的值,然后将该结果赋给一个变量。
例如“N=N+1”的作用是用N的当前值加上1后再送入N中,假设N的当前值是5,则执行N=N+1后,N的值为6。
(4)根据赋值语句的功能,由于赋值号的方向性特性,赋值号左边只能是变量,以便提供一个获得数据的空间。
因此,“A=B”和“B=A”具有完全不同的意义,前者表示将B中的数据送入A中,后者表示将A中的数据送入B中。
语句“X+Y=10”是错误的,因为在内存中找不到名字为X+Y的变量。
2)执行赋值语句时的类型转换问题执行赋值操作时,被赋值的变量和表达式的类型可以相同,也可以不相同。
FORTRAN语言作如下规定:(1)变量与表达式的类型相同,则将表达式的结果直接赋值。
M=4 (变量M和4都是整型)A=3.5*SIN(X)(变量A和表达式3.5*SIN(X)都是实型)(2)如果类型不同,则应先进行表达式的计算,然后将该表达式的值转换为被赋值变量的类型。
在matlab中读netCDF格式⽂件的⼀些函数matlab中读nc的函数在matlab中读netCDF格式⽂件的⼀些函数A.⽂件IO操作函数:1.打开netCDF数据⽂件ncid = netcdf.open(filename, mode) mode:'NC_WRITE','NC_SHARE','NC_NOWRITE' 2.还原最近的netCDF⽂件定义netcdf.abort(ncid)3.关闭netCDF⽂件netcdf.close(ncid)4.创建新netCDF数据⽂件ncid = netcdf.create(filename, mode)mode:'NC_NOCLOBBER': Prevent overwriting of existing file with the same name.'NC_SHARE': Allow synchronous file updates. 'NC_64BIT_OFFSET': Allow easier creation of files and variables which are larger than two gigabytes.5.完成netCDF⽂件定义模式netcdf.endDef(ncid)netcdf.endDef(ncid,h_minfree,v_align,v_minfree,r_align)6.返回已知netCDF库常数的列表val = netcdf.getConstantNames如:nc_constants = netcdf.getConstantNamesnc_constants ='NC2_ERR''NC_64BIT_OFFSET''NC_BYTE''NC_CHAR''NC_CLOBBER''NC_DOUBLE''NC_EBADDIM''NC_EBADID''NC_EBADNAME''NC_EBADTYPE'...7.返回数值的命名常数val = netcdf.getConstant(param_name)param_name为netcdf.getConstantNames中的string类型的值。
netcdf4.1.3安装后环境变量设置以及Qt下使用静态动态库方法一.netcdf4.1.3安装后环境变量设置1.下载netcdf安装包,from:/downloads/netcdf/index.jsp我下载的是版本4.1.32.解压tar -zxvf netcdf-4.1.3.tar.gz3. 在解压后的netcdf-4.1.3所在目录执行:./configure --disable-dap --disable-netcdf-4 --prefix=/usr/local/netcdf注意:上面红色的两个选项是他人很多次实验后证明必须的(参考资料1)。
--disable-dap的原因是缺少一个‘curl’的lib,--disable-netcdf-4是报错中提出的解决办法,尽管我个人暂时没有搞清楚为什么。
不写这两个,在configure的时候就会报错,导致后面make失败。
4. make5. make install,提示安装成功的同时,还会提醒make check,下一步进行。
6. make check安装完成后,/usr/local/netcdf/文件夹下存在4个文件,分别为bin,include,lib和share安装完成后,注意环境变量的设置打开终端输入sudo ~/.bashrc在最后添加exportPATH=/home/swh/NSForWoss/DESERT_all_in_one_1.0.0/netcdf/bin:/$P ATHexportLD_LIBRARY_PATH=/home/swh/NSForWoss/DESERT_all_in_one_1.0 .0/netcdf/lib:/$ LD_LIBRARY_PATHexportDYLD_LIBRARY_PATH=/home/swh/NSForWoss/DESERT_all_in_one _1.0.0/netcdf/lib:/$ DYLD_LIBRARY_PATH测试环境变量是否生效输入ncdump会出现如下阴影区域,说明安装成功二.Qt下使用静态动态库方法要想读取netcdf文件(后缀为.nc),我们需要使用上面安装的nefcdf。
nc文件压缩函数
你可能是在说.nc文件,这是一种NetCDF(网络通用数据格式)文件,常用于存储大量科学数据。
NetCDF是一种数据存储格式,而不是一种编程语言或算法。
因此,压缩这种文件通常需要使用特定的工具或库,而不是直接在代码中编写一个函数。
对于.nc文件的压缩,你可以使用NetCDF库提供的工具,如`ncpdq`(用于数据重新排序和压缩)或`ncpack`(用于打包和压缩NetCDF文件)。
这些工具通常需要单独安装,并且通常作为NetCDF库的一部分提供。
如果你需要在Python中处理.nc文件,可以使用netCDF4库。
netCDF4库提供了一些方法来读取和写入NetCDF文件,并且可以自动处理压缩和其他格式特性。
如果你需要压缩.nc文件,可以使用类似于以下代码的Python脚本:
```python
from netCDF4 import Dataset
打开.nc文件
nc_file = Dataset('', 'a', format='NETCDF4')
压缩文件
nc_()
```
注意,这个代码示例使用的是netCDF4库的`Dataset`类来打开一个.nc文件,并使用`format='NETCDF4'`参数来指定使用NetCDF4格式。
关闭文件时,库会自动压缩和保存更改。
如果你需要在其他编程语言中压缩.nc文件,你需要查找特定于该语言的库或工具,或者手动处理文件的二进制格式。
具体的实现将取决于你使用的编程语言和库。
NetCDF简介与格式⼊门最近研究⼤数据,⽤到了NetCDF⽂件的解析,于是搜索了⽹络上的相关资源,记录⼀下。
⼀、概述NetCDF全称为network Common Data Format,中⽂译法为“⽹络通⽤数据格式”,它是由美国⼤学⼤⽓研究协会的Unidata项⽬科学家针对科学数据的特点开发的,是⼀种⾯向数组型并适于⽹络共享的数据描述和编码标准。
NetCDF和zip、jpeg、bmp⽂件格式类似,都是⼀种⽂件格式的标准。
NetCDF⽂件开始时⽬的是⽤于存储⽓象科学中的数据,现在已经成为许多数据采集软件⽣成⽂件的格式。
利⽤NetCDF可以对⽹络数据进⾏⾼效地存储、管理、获取和分发等操作。
由于其灵活性,能够传输海量的⾯向阵列(array-oriented)数据,⽬前⼴泛应⽤于⼤⽓科学、⽔⽂、海洋学、环境模拟、地球物理等诸多领域。
从数学上来说,netcdf存储的数据就是⼀个多⾃变量的单值函数。
⽤公式来说就是f(x,y,z,...)=value,函数的⾃变量x,y,z等在netcdf中叫做维(dimension)或坐标轴(axis),函数值value在netcdf中叫做变量(Variables)。
⽽⾃变量和函数值在物理学上的⼀些性质,⽐如计量单位(量纲)、物理学名称等等在netcdf中就叫属性(Attributes)。
⼆、相关⽹站三、⽂件格式NetCDF⽂件后缀为.nc,⽂件中的数据结构包含维(dimensions)、变量(variables)和属性(attributes)三种描述类型,每种类型都会被分配⼀个名字和⼀个ID。
NetCDF name{Dimensions:… //定义维数Variables:… //定义变量Attributes:… //属性Data:…//数据}1. 变量(Variables)变量对应着真实的物理数据。
⽐如我们家⾥的电表,每个时刻显⽰的读数表⽰⽤户的到该时刻的耗电量。
.nc 文件的查看和处理2013-08-04 12:45阅读:2,168最近在学习冰后回弹模型(http://www.atmosp.physics.utoronto.ca/~peltier/data.php),里面给出的数据为nc(netcdf)格式的,读取是个问题,在言深深的帮助下,成功读取,在这里将其总结出来,以备后用也希望可以方便有用之人。
有两种方式可以进行读取:1、Excel的一个插件,NetCDF4Excel可以完成相关的查看工作,需要的可以进行下载(/c0lngehgha),/share/link? ... 416233&third=15(华为网盘太不靠谱,不知道百度靠谱到合适)安装之后,我们可以得到,一个快捷方式,如图:打开之后,我们可以看到下面的情形:然后打开nc文件,我们就可以进行查看操作:2、通过Grads进行相关的读取,主要是在言深深同学的帮助下完成,深深的感谢!第一步,安装相关的grads软件,这个这里不做介绍,相关可以论坛网站;第二步,打开grads软件,如图,回车之后的那个窗口千万不能关,那个窗口是图像显示的,关闭之后输入命令之后直接就退出了,刚开始我老犯这个低级错误(对菜鸟而言)。
第三步,可以通过两个命令简单的看到数据的头文件包含信息:①sdfopen d:\1.nc②q ctlinfo然后编写gs文件,如下:'reinit''sdfopen D:\1.nc''set gxout fwrite''se t fwrite D:\1.dat''set x 1 360''set y 1 179''set z 1''set t 1 1''d dsea_250''disable fwrite'ps1:路径自己可以按需更改,不要有空格。
fortran文件操作From: 《Fortran 95 程序设计》彭国伦1.文件读取的概念:读取:“顺序读取”和“直接读取”。
保存:“文本文件”和“二进制文件”。
二进制文件:读取快,因为保存格式和数据在内存中的保存方法一样,同时也节省空间。
----------------------------------2. 文件的操作:----------------------------------open的使用:使用open命令打开文件之后,就可以对文件来做输入输出。
example:program ex0901impicit noneopen(unit=10, file='hello.txt') ! 打开hello.txt文件, unit指定文件代码,file 指定文件名称。
write(10, *) "hello" !在代码为10的文件中写入hellostopend program ex0901open中有很多参数可以使用,详细如下:OPEN(UNIT=number, FILE='filename', FORM='...', STATUS='...', ACCESS='...', RECL=length, ERR=label, IOSTAT=iostat, BLANK='...', POSITION='...', ACTION=action, PAD='...', DELIM='...')UNIT='number': number必须是一个正整数,它可以使用变量或是常量来赋值。
number最好避开1,2,5,6。
因为2,6是默认的输出位置,也就是屏幕。
1,5则是默认的输入位置,键盘。
FILE='filename':指定要打开的文件名称,文件名要符合系统规定。
Introduction to using the netCDF data format with Fortran 90Michael Thorne (michael.thorne@)Last Updated: July 20, 2010I. IntroductionNetCDF – Net work C ommon D ata F ormNetCDF is an array based data structure for storing multidimensional data. A netCDF file is written with an ASCII header and stores the data in a binary format. The space saved by writing binary files is an obvious advantage, particularly because one does not need worry about the byte order. Any byte-swapping is automatically handled by the netCDF libraries and a netCDF binary file can thus be read on any platform. Some features associated with using the netCDF data format are as follows: Coordinate systems: support for N-dimensional coordinate systems.•X-coordinate (e.g., lat)•Y-coordinate (e.g., lon)•Z-coordinate (e.g., elevation)•Time dimension•Other dimensionsVariables: Support for multiple variables.• E.g., S-wave velocity, P-wave velocity, density, stress components…Geometry: Support for a variety of grid types (implicit or explicit).•Regular grid (implicit)•Irregular grid•PointsSelf-Describing: Dataset can include information defining the data it contains.•Units (e.g., km, m/sec, gm/cm3,…)•Comments (e.g., titles, conventions used, names of variables (e.g., P-wave velocity), names of coordinates (e.g., km/sec),...Full documentation on the data format can be found at:•/software/netcdf/ - netCDF webpage•/software/netcdf/docs/ - Full netCDF documentation•/software/netcdf/docs/netcdf-f90/ - F90 Interface guideNaming convention: NetCDF files are generally named with the .nc extension.File conventions: There are many different flavors or conventions of netCDF data. In seismology the example most people are familiar with are the .grd files produced with the Generic Mapping Tools (/). Writing netCDF files to use with GMT requires using the COARDS (“Cooperative Ocean/Atmosphere Research Data Service”) data convention. The specifics of this convention can be found at: /noaa_coop/coop_cdf_profile.html.One of the specific reasons I have started using netCDF files is that the grid information can also be stored along with the data. Hence when using a program like GMT I don’t explicitly have to write an xyz2grd command to plot the data or try to remember for the particular file I am plotting what the Range (-R option in GMT) or grid increment (-I option) are. However, when using the COARDS convention one is limited to rectilinear coordinate systems. The coordinates do not have to be evenly spaced, but must at least be either monotonically increasing or decreasing. Unfortunately GMT cannot handle irregularly spaced grids without preconditioning the data with a command like blockmean. Visualization: Another obvious advantage of using the netCDF format is that a variety of data viewers already exist. Additionally nearly all visualization packages that I am familiar with read the netCDF format. Some popular free viewers or visualization packages are:•Ncview - /~pierce/ncview_home_page.html•Data Explorer (OpenDX) - /II. File StructureA netCDF file contains the following structures.NetCDF file contains:Global Attributes: Describe the contents of the file.Dimensions: Define the structure of the data (e.g., time, depth, lat, lon).Variables: Holds the data in arrays shaped by dimensionsVariable Attributes: Describes the content of each variable.III. Compiling and LinkingThe examples shown are using the flags available with the g95 compiler. In order to use netCDF with f90 you need to have the f90 netcdf module installed. This module should be located in your netCDF installation directory under: include/netcdf.mod. If this module isn't there you may need to reinstall netCDF.To compile a module with subroutines that uses netcdf calls. A possible module file will have the following setup:MODULE exampleCONTAINSSUBROUTINE sub1( )USE netcdfIMPLICIT NONE...END SUBROUTINE sub1...END MODULE exampleAs shown in this example, you must make the netCDF subroutines available to your subroutine by the USE netcdf statement.If this module is called example.f90 then it can be compiled by:>> g95 -c example.f90 -I$(NETCDF)/includeWhere $(NETCDF) is a shell variable providing the path to the netCDF installation. The -I option in g95 tells the compiler where to look for the netcdf.mod module.Compiling and linking a program (e.g., 'main.f90') to the pre-compiled example.o module from above is then done by:>> g95 main.f90 -o main.x ./example.o-L$(NETCDF)/lib -lnetcdfWhere the -L and -l options must be specified (for g95 - see compiler specific flags) if the netCDF libraries are not already in your path.IV. UtilitiesNetCDF comes with a couple of useful utilities that should be located in the bin/ directory of your netCDF installation.ncdump: generate an ASCII representation of a specified netCDF file to standard output.To just show the header information:>> ncdump –h filename.ncncgen: this can be used to generate a netCDF file.V. Example - Reading a netCDF file with F90To read a netCDF file into a f90 program when you have no information about the size or names of the variables, the order of the library calls to use is as follows:NF90_OPEN ! open existing netCDF datasetNF90_INQUIRE ! find out what is in itNF90_INQUIRE_DIMENSION ! get dimension names, lengthsNF90_INQUIRE_VARIABLE ! get variable names, types, shapesNF90_INQ_ATTNAME ! get attribute namesNF90_INQUIRE_ATTRIBUTE ! get other attribute informationNF90_GET_ATT ! get attribute valuesNF90_GET_VAR ! get values of variablesNF90_CLOSE ! close netCDF datasetAs an example, consider reading a 2D GMT grid file into a F90 program. The first thing I want to do in my program is determine the size of the grid. I can accomplish this by making a call to the supplied subroutine griddims…CALL griddims(infile,NX,NY)Where infile is the name of the netCDF file I want to read in and NX and NY are integers that will hold the size of the grid file.!GRIDDIMS - Get dimensions of a netCDF 2D gridfile!:====================================================================== SUBROUTINE griddims(infile,NX,NY)USE netcdfIMPLICIT NONEINTEGER(KIND=4), INTENT(OUT) :: NX, NYINTEGER(KIND=4) :: ncidCHARACTER(LEN=50), INTENT(IN) :: infileCHARACTER(LEN=50) :: xname, yname!Open netCDF file!:-------:-------:-------:-------:-------:-------:-------:CALL check(nf90_open(infile, nf90_nowrite, ncid))!Inquire about the dimensions!:-------:-------:-------:-------:-------:-------:-------:CALL check(nf90_inquire_dimension(ncid,1,xname,NX))CALL check(nf90_inquire_dimension(ncid,2,yname,NY))!Close netCDF file!:-------:-------:-------:-------:-------:-------:-------:CALL check(nf90_close(ncid))END SUBROUTINE griddims!:======================================================================Now that I have my grid dimensions I can allocate an array to hold the data:ALLOCATE(indata(NX,NY))ALLOCATE(xpos(NX))ALLOCATE(ypos(NY))Where I will put the data in the array indata, and the X- and Y- grid locations in the arrays xpos and ypos respectively. And now I can make a subroutine call to readgrid to get the data out of the netCDF file.CALL readgrid(infile,xpos,ypos,indata,NX,NY)Now you can do whatever you want with the netCDF data! Of special note though, the subroutine provided in this example is not completely generalized. One can write routines to read in completely generic netCDF files. In this example, I know that I am reading a 2D grid, and that the x-coordinate positions are written to the first variable, the y-coordinate positions are written to the second variable, and the array data is written to the third variable.!READGRID - read a netCDF gridfile!:======================================================================== SUBROUTINE readgrid(infile,xpos,ypos,idata,NX,NY)USE netcdfIMPLICIT NONEREAL(KIND=4), DIMENSION(NX), INTENT(OUT) :: xposREAL(KIND=4), DIMENSION(NY), INTENT(OUT) :: yposREAL(KIND=4), DIMENSION(NX,NY), INTENT(OUT) :: idataINTEGER(KIND=4), INTENT(IN) :: NX, NYINTEGER(KIND=4), DIMENSION(2) :: dimidsINTEGER(KIND=4) :: ncid, xtype, ndims, varidCHARACTER(LEN=50), INTENT(IN) :: infileCHARACTER(LEN=50) :: xname, yname, vname!Open netCDF file!:-------:-------:-------:-------:-------:-------:-------:-------:CALL check(nf90_open(infile, nf90_nowrite, ncid))!Get the values of the coordinates and put them in xpos & ypos!:-------:-------:-------:-------:-------:-------:-------:-------:CALL check(nf90_inquire_variable(ncid,1,vname,xtype,ndims,dimids))CALL check(nf90_inq_varid(ncid,vname,varid))CALL check(nf90_get_var(ncid,varid,xpos))CALL check(nf90_inquire_variable(ncid,2,vname,xtype,ndims,dimids))CALL check(nf90_inq_varid(ncid,vname,varid))CALL check(nf90_get_var(ncid,varid,ypos))!Get the values of the perturbations and put them in idata!:-------:-------:-------:-------:-------:-------:-------:-------:CALL check(nf90_inquire_variable(ncid,3,vname,xtype,ndims,dimids))CALL check(nf90_inq_varid(ncid,vname,varid))CALL check(nf90_get_var(ncid,varid,idata))!Close netCDF file!:-------:-------:-------:-------:-------:-------:-------:-------:CALL check(nf90_close(ncid))END SUBROUTINE readgrid!:=========================================================================The subroutine readgrid utilizes the subroutine check, which will return a netCDF error and stop execution of the code if netCDF encounters an error.!Check (ever so slightly modified from )!:====================================================================== SUBROUTINE check(istatus)USE netcdfIMPLICIT NONEINTEGER, INTENT (IN) :: istatusIF (istatus /= nf90_noerr) THENwrite(*,*) TRIM(ADJUSTL(nf90_strerror(istatus)))END IFEND SUBROUTINE check!:======================================================================VI. Example - Writing a netCDF file with F90To write a netCDF file from a F90 program the order of the library calls to use is as follows:NF90_CREATE ! create netCDF dataset: enter define modeNF90_DEF_DIM ! define dimensions: from name and lengthNF90_DEF_VAR ! define variables: from name, type, dimsNF90_PUT_ATT ! assign attribute valuesNF90_ENDDEF ! end definitions: leave define modeNF90_PUT_VAR ! provide values for variableNF90_CLOSE ! close: save new netCDF datasetIn the following example I show a simple way to write a 2D array of data into a netCDF file. Here is an example where I just make up a cosine variation on a globe:PROGRAM exIMPLICIT NONEREAL(KIND=4), DIMENSION(:,:), ALLOCATABLE :: mydata REAL(KIND=4), DIMENSION(:), ALLOCATABLE :: xpos, ypos REAL(KIND=4) :: x, yINTEGER(KIND=4) :: NXINTEGER(KIND=4) :: NYINTEGER(KIND=4) :: J, KCHARACTER(LEN=50) :: outfileoutfile ='ex1.nc'NX =360NY =180ALLOCATE(mydata(NX,NY))ALLOCATE(xpos(NX))ALLOCATE(ypos(NY))!Populate X and Y grid locationsx =-179.0DO J=1,NXxpos(J) = xx = x + 1.0ENDDOy =-90.0DO J=1,NYypos(J) = yy = y + 1.0ENDDO!make up some dataDO J=1,NXx = xpos(J)DO K=1,NYy = ypos(K)mydata(J,K) =cos(sqrt(x*x+y*y)/10.0)ENDDOENDDO!write netCDF fileCALL writegrid(outfile,xpos,ypos,mydata,NX,NY)END PROGRAM exThis program uses the following writegrid subroutine:!WRITEGRID - write a netCDF gridfile!:========================================================================= SUBROUTINE writegrid(outfile,xpos,ypos,idata,NX,NY)USE netcdfIMPLICIT NONEREAL(KIND=4), DIMENSION(NX), INTENT(IN) :: xposREAL(KIND=4), DIMENSION(NY), INTENT(IN) :: yposREAL(KIND=4), DIMENSION(NX,NY), INTENT(IN) :: idataINTEGER(KIND=4) :: ncid, x_dimid, y_dimidINTEGER(KIND=4) :: x_varid, y_varid, varidINTEGER(KIND=4), DIMENSION(2) :: dimidsINTEGER(KIND=4), INTENT(IN) :: NX, NYCHARACTER(LEN=50), INTENT(IN) :: outfile!Create the netCDF file.CALL check(nf90_create(outfile, NF90_CLOBBER, ncid))!Define the dimensions.CALL check(nf90_def_dim(ncid, "lon", NX, x_dimid))CALL check(nf90_def_dim(ncid, "lat", NY, y_dimid))!Define coordinate variablesCALL check(nf90_def_var(ncid, "lon", NF90_REAL, x_dimid, x_varid))CALL check(nf90_def_var(ncid, "lat", NF90_REAL, y_dimid, y_varid))dimids = (/ x_dimid, y_dimid /)!Define variableCALL check(nf90_def_var(ncid, "Perturbations", NF90_FLOAT, dimids, varid)) CALL check(nf90_enddef(ncid)) !End Definitions!Write DataCALL check(nf90_put_var(ncid, x_varid, xpos))CALL check(nf90_put_var(ncid, y_varid, ypos))CALL check(nf90_put_var(ncid, varid, idata))CALL check(nf90_close(ncid))END SUBROUTINE writegrid!:=========================================================================VII. Example – Adding units and other attributesUnits and other attributes are easily added to a netCDF file. There are some standard attributes that can be added. A list of these standard attributes is given at:/software/netcdf/docs/netcdf-f90/Attribute-Conventions.html#Attribute-ConventionsA couple of the most useful attributes are:A few standard attributes:long_name A long descriptive name. This could be used for labeling plots, for example.valid_min A scalar specifying the minimum valid value for this variable.valid_max A scalar specifying the maximum valid value for this variable.title A global attribute that is a character array providing a succinct description of what is in the dataset.history A global attribute for an audit trail. This is a character array with a line for each invocation of a program that has modified the dataset.Here I show a brief example of how to go about doing this. The first steps of opening a file and making the definitions are done as in the example of the previous section:!Create the netCDF file.CALL check(nf90_create(outfile, NF90_CLOBBER, ncid))!Define the dimensions.CALL check(nf90_def_dim(ncid, "lon", NX, x_dimid))CALL check(nf90_def_dim(ncid, "lat", NY, y_dimid))!Define coordinate variablesCALL check(nf90_def_var(ncid, "lon", NF90_REAL, x_dimid, x_varid))CALL check(nf90_def_var(ncid, "lat", NF90_REAL, y_dimid, y_varid))Now we can add units for the coordinate variablesCALL check(nf90_put_att(ncid, x_varid, ”units”, “deg”))CALL check(nf90_put_att(ncid, y_varid, “units”, “deg”))Next we define our data array:dimids = (/ x_dimid, y_dimid /)!Define variableCALL check(nf90_def_var(ncid, "Perturbations", NF90_FLOAT, dimids, varid)) And now we can add units to the data array:CALL check(nf90_put_att(ncid, varid, “units”, “dVs %”))Besides units we can add any other type of attribute we like. Some conventions have named attributes which individual software packages will understand – e.g., the “units” attribute given above is standard. But, we can add anything we like. For example, in this example I may have used a special kind of function, e.g., a Matern function, to create to the perturbations that I want to document in the file. I can add this by:CALL check(nf90_put_att(ncid, varid, “Function_Type”, “Matern”))We can also add global attributes such as a title where instead of giving a variable ID we use theF90_GLOBAL specifier:CALL check(nf90_put_att(ncid,NF90_GLOBAL, “title”, “Realization by KL Expansion”))Now that I am done adding attributes I must end the definining stage:CALL check(nf90_enddef(ncid)) !End DefinitionsAnd now I can write the data:!Write DataCALL check(nf90_put_var(ncid, x_varid, xpos))CALL check(nf90_put_var(ncid, y_varid, ypos))CALL check(nf90_put_var(ncid, varid, idata))CALL check(nf90_close(ncid))VIII. Example – Irregularly spaced dataThere is no real standard for handling irregularly spaced data. However, some conventions have been defined for specific packages. Here I show how to write irregularly spaced data into a format that can be read by OpenDX.Here is a sample program to generate some test data on an irregular grid:PROGRAM exIMPLICIT NONEREAL(KIND=4), DIMENSION(:,:), ALLOCATABLE :: positionsREAL(KIND=4), DIMENSION(:), ALLOCATABLE :: mydataREAL(KIND=4) :: x, yINTEGER(KIND=4) :: NX, NY, naxesINTEGER(KIND=4) :: JCHARACTER(LEN=50) :: outfileoutfile ='ex1.nc'NX =2NY =2naxes =2ALLOCATE(mydata(NX*NY))ALLOCATE(positions(naxes,NX*NY))positions(1:2,1) = (/0.0, 0.0/)positions(1:2,2) = (/0.0, 0.2/)positions(1:2,3) = (/0.3, 0.5/)positions(1:2,4) = (/0.4, 0.9/)DO J=1,NX*NYx = positions(1,J)y = positions(2,J)mydata(J) =cos(sqrt(x*x+y*y)/10.0)ENDDO!write netCDF fileCALL wirrgrid(outfile,positions,mydata,NX*NY,naxes)END PROGRAM exThe grid positions are stored in an array, where each line of the array gives the x, and y coordinate (and z, etc. if appropriate) for each data value in the vector mydata.The accompanying subroutine to write the netCDF file is:!WIRRGRID - write a netCDF gridfile!:========================================================================= SUBROUTINE wirrgrid(outfile,positions,idata,pointnums,axes)USE netcdfIMPLICIT NONEREAL(KIND=4), DIMENSION(axes,pointnums), INTENT(IN) :: positionsREAL(KIND=4), DIMENSION(pointnums), INTENT(IN) :: idataINTEGER(KIND=4) :: ncid, x_dimid, y_dimid, d_dimidINTEGER(KIND=4) :: x_varid, y_varid, varidINTEGER(KIND=4), DIMENSION(2) :: dimidsINTEGER(KIND=4), INTENT(IN) :: pointnums, axesINTEGER(KIND=4) :: J, K, cCHARACTER(LEN=50), INTENT(IN) :: outfile!Create the netCDF file.CALL check(nf90_create(outfile, NF90_CLOBBER, ncid))!Define the dimensions.CALL check(nf90_def_dim(ncid, "pointnums", pointnums, x_dimid))CALL check(nf90_def_dim(ncid, "axes", axes, y_dimid))!Dimension ID'sdimids = (/ y_dimid, x_dimid /)!Define coordinate variablesCALL check(nf90_def_var(ncid, "grid", NF90_FLOAT, dimids, x_varid))!Define data variableCALL check(nf90_def_var(ncid, "Perturbations", NF90_FLOAT, x_dimid, varid)) !Add attributesCALL check(nf90_put_att(ncid,varid,"units","%"))CALL check(nf90_put_att(ncid,varid,"field","Perturbations, vector"))CALL check(nf90_put_att(ncid,varid,"positions","grid"))CALL check(nf90_enddef(ncid)) !End Definitions!Write DataCALL check(nf90_put_var(ncid, x_varid, positions))CALL check(nf90_put_var(ncid, varid, idata))CALL check(nf90_close(ncid))END SUBROUTINE wirrgrid!:========================================================================= In this example, using OpenDX, the variable with our data, Perturbations, must have the field and positions attribute set as above so OpenDX knows where to look for the grid positions.IX. Reading netCDF with MatlabTo read netCDF files into matlab a couple collections of m-files are required. The first is the CSIRO netCDF/OPeNDAP interface to matlab. These are just a collection of m-files which can be obtained from: http://www.marine.csiro.au/sw/matlab-netcdf.html#installationTo use them you should grab them (cp –r) and add them to your matlab search path, e.g.,in matlab:>> addpath /home/mthorne/applications/matlab/mfiles/matlab_netCDF_OPeNDAP/ You also need the mexnc netCDF mexfiles. These can be grabbed at/downloadsAs above you just need to add these to your search path.Now once in matlab you can simply read a netCDF file by:>> mydata = getnc(‘foo.nc’);This will interactively prompt you for which variable you want. If e.g., foo.nc contains a 2-D grid file written in a matrix, you can return this data into the variable mydata and then start to do work on it, e.g., imagesc(mydata).。