爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 5403|回复: 10

使用MeteoInfoC.dll如何创建一个和已有结构一样的nc文件

[复制链接]

新浪微博达人勋

发表于 2013-1-30 10:27:10 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
我有一个nc文件,目前需要做两个工作:
1)将原有的含60年资料的文件按月取平均值(此步骤已在楼主的指导下完成)。
2)要将计算好的平均值数据(12个月的数据最终得到了12个GridData数据)重新写一个nc文件,要求和原文件结构一样


  1. NetCDFDataInfo gridFile = new NetCDFDataInfo();
  2.             gridFile.CreateNCFile(Application.StartupPath + "\\Sample\\result.nc");

  3. //... 如何将GridData数据写入到相应的变量中?

密码修改失败请联系微信:mofangbao

新浪微博达人勋

0
早起挑战累计收入
发表于 2013-1-30 10:56:40 | 显示全部楼层
貌似有python下脚本的例子,看看这个有帮助没:
http://bbs.06climate.com/forum.php?mod=viewthread&tid=5485
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2013-1-30 11:23:26 | 显示全部楼层
十分感谢,这个贴子很有作用。做完了我把源码献上。
还有一个帖子也很有用:
http://hi.baidu.com/meteoinfo/item/369f9a2279ed661e2a0f1ce3
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2013-1-30 13:34:00 | 显示全部楼层
请高人指点,目前我想要的效果已经基本可以实现了,即:
1)求历年12个月数据各个月的平均值,求完放在 mdatas数组中(mdatas 为 GridData[12])。
2)创建result.nc文件,希望将计算结果(即历年12个月数据各个月的平均值mdatas)保存到新的文件中。nc的格式需要同原来的数据格式相同。

注:目前我将每个月的数据都存为一个nc文件没有问题。可是不知道如何将12个月的数据都存在一个文件中。
先贴代码再解释我的做法。

  1. NetCDFDataInfo aDataInfo = new NetCDFDataInfo();
  2.             string aFile = Application.StartupPath + "\\Sample\\Hadisst_obs_1949-2010_T106_BCC_AGCM2.1.nc";
  3.             //读取nc文件
  4.             aDataInfo.ReadDataInfo(aFile);
  5.             var t = aDataInfo.times;
  6.             List<GridData>[] datas = new List<GridData>[12];
  7.             int sYear = aDataInfo.times[0].Year;
  8.             int eYear = aDataInfo.times[aDataInfo.times.Count - 1].Year;
  9.             int yIndex = 0;
  10.             GridData gData = new GridData();
  11.             //循环年份
  12.             for (int startYear = 1961; startYear < eYear; startYear++)
  13.             {
  14.                 yIndex = startYear - sYear;
  15.                 //将每年12个月的数据都摆在相应月份的数组里
  16.                 for (int mIndex = 0; mIndex < 12; mIndex++)
  17.                 {
  18.                     List<GridData> mList = datas[mIndex];
  19.                     if (mList == null)
  20.                     {
  21.                         mList = new List<GridData>();
  22.                     }
  23.                     mList.Add(aDataInfo.GetGridData_LonLat(yIndex * 12 + mIndex, 4, 0));
  24.                     datas[mIndex] = mList;
  25.                 }
  26.             }
  27.             GridData[] mdatas = new GridData[12];
  28.             //对每个月份的数据计算平均值
  29.             for (int mIndex = 0; mIndex < 12; mIndex++)
  30.             {
  31.                 List<GridData> mList = datas[mIndex];
  32.                 mdatas[mIndex] = DataMath.Average(mList, false);
  33.             }
  34.             NetCDFDataInfo gridFile = new NetCDFDataInfo();
  35.             string outFilePath = Application.StartupPath + "\\Sample\\result.nc";
  36.             gridFile.fileName = outFilePath;
  37.             gridFile.UNDEF = aDataInfo.UNDEF;
  38.             gridFile.unlimdimid = aDataInfo.unlimdimid;
  39.             // Add dimensions:
  40.             foreach (var dimension in aDataInfo.dimList)
  41.             {
  42.                 gridFile.AddDimension(dimension);
  43.             }
  44.             object[] lonDatas = new object[160];
  45.             object[] latDatas = new object[320];
  46.             // Add variables
  47.             foreach (Variable variable in aDataInfo.varList)
  48.             {
  49.                 gridFile.AddVariable((Variable)variable.Clone());
  50.                 //Add variable attributes
  51.                 foreach (var attribute in variable.Attributes)
  52.                 {
  53.                     gridFile.AddVariableAttribute(variable.Name, attribute.attName, attribute.attValue.ToString());
  54.                 }
  55.                 if (variable.Name == "lon")
  56.                 {
  57.                     aDataInfo.GetVarData(variable, ref lonDatas);
  58.                 }
  59.                 if (variable.Name == "lat")
  60.                 {
  61.                     aDataInfo.GetVarData(variable, ref latDatas);
  62.                 }
  63.             }
  64.             //Add global attributes
  65.             foreach (var globalAttribute in aDataInfo.gAttList)
  66.             {
  67.                 gridFile.AddGlobalAttribute(globalAttribute.attName, globalAttribute.attValue.ToString());
  68.             }
  69.             //Create netCDF file
  70.             gridFile.CreateNCFile(outFilePath);
  71.             gridFile.WriteVar("lon", lonDatas);
  72.             gridFile.WriteVar("lat", latDatas);
  73.             //Add Time
  74.             int[] startArray = new int[1];
  75.             int[] countArray = new int[1];
  76.             double[] dataArray = new double[12];
  77.             for (int mIndex = 0; mIndex < 12; mIndex++)
  78.             {
  79.                 dataArray[mIndex] = mIndex;
  80.             }
  81.             startArray[0] = 0;
  82.             countArray[0] = 1;
  83.             gridFile.WriteVara("time", startArray, countArray, dataArray);

  84.             //Add Data
  85.             int[] startdataArray = new int[3];
  86.             int[] countdataArray = new int[3];
  87.             startdataArray[0] = 0;
  88.             startdataArray[1] = 0;
  89.             startdataArray[2] = 0;
  90.             countdataArray[0] = 12;
  91.             countdataArray[1] = aDataInfo.Y.Length;
  92.             countdataArray[2] = aDataInfo.X.Length;
  93.             
  94.             //创建一个可以盛放12个月数据的数组(从这个地方开始就不知道对不对了)
  95.             double[] dataResult = new double[aDataInfo.X.Length * aDataInfo.Y.Length * 12];
  96.             int dataIndex = 0;
  97.             //循环12个月的数据
  98.             for (int mIndex = 0; mIndex < 12; mIndex++)
  99.             {
  100.                 //获取每个月的数据
  101.                 var ddt = mdatas[mIndex].Data;
  102.                 //将每个月的数据转换为数组赋值
  103.                 for (int y = 0; y < aDataInfo.Y.Length; y++)
  104.                 {
  105.                     for (int x = 0; x < aDataInfo.X.Length; x++)
  106.                     {
  107.                         dataResult[dataIndex] = ddt[y, x];
  108.                         dataIndex++;
  109.                     }
  110.                 }
  111.             }
  112.             // gridFile.w
  113.             gridFile.WriteVara("SST_cpl", startdataArray, countdataArray, dataResult);
  114.             gridFile.CloseNCFile();


各位看官请看源码的最下面,我开始测试,如果我这么写:


  1. //Add Data
  2. int[] startdataArray = new int[3];
  3. int[] countdataArray = new int[3];
  4. startdataArray[0] = 0;
  5. startdataArray[1] = 0;
  6. startdataArray[2] = 0;
  7. countdataArray[0] = 12;
  8. countdataArray[1] = aDataInfo.Y.Length;
  9. countdataArray[2] = aDataInfo.X.Length;

  10.   //创建一个可以盛放数据的数组
  11. double[] dataResult = new double[aDataInfo.X.Length * aDataInfo.Y.Length ];
  12. int dataIndex = 0;
  13. //获取1月份的数据
  14. var ddt = mdatas[0].Data;
  15. //将每个月的数据转换为数组赋值
  16. for (int y = 0; y < aDataInfo.Y.Length; y++)
  17. {
  18. for (int x = 0; x < aDataInfo.X.Length; x++)
  19. {
  20. dataResult[dataIndex] = ddt[y, x];
  21. dataIndex++;
  22. }
  23. }
  24. // 写变量数据
  25. gridFile.WriteVara("SST_cpl", startdataArray, countdataArray, dataResult);



目前最大的问题就是多个时间尺度的数据如何保存。
startdataArray, countdataArray, dataResult三个变量都是怎么设置的?
说实话我都是依葫芦画瓢,希望王老师或其他高手能再给点指导。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2013-1-30 14:19:43 | 显示全部楼层
很急,在线等。。。各位大侠出来帮忙看看
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-1-30 14:50:56 | 显示全部楼层

可以参考此帖:MeteoInfo脚本示例:MICAPS第4类数据转为NetCDF
http://bbs.06climate.com/forum.p ... 630&fromuid=106
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2013-1-30 15:41:21 | 显示全部楼层
本帖最后由 看天吃饭 于 2013-1-30 16:02 编辑
MeteoInfo 发表于 2013-1-30 14:50
可以参考此帖:MeteoInfo脚本示例:MICAPS第4类数据转为NetCDF
http://bbs.06climate.com/forum.php?mod ...


王老师,按照那个方式,我调整了一下关键代码,好像现在写的数据不对了。

  1. //创建一个可以盛放12个月数据的数组(从这个地方开始就不知道对不对了)
  2.             double[] dataResult = new double[aDataInfo.X.Length * aDataInfo.Y.Length];


  3.             //Add Data
  4.             int[] startdataArray = new int[4];
  5.             int[] countdataArray = new int[4];

  6.             //循环12个月的数据
  7.             for (int mIndex = 0; mIndex < 12; mIndex++)
  8.             {
  9.                 dataResult = new double[aDataInfo.X.Length * aDataInfo.Y.Length];
  10.                 int dataIndex = 0;
  11.                 //获取每个月的数据
  12.                 var ddt = mdatas[mIndex].Data;

  13.                 //将每个月的数据转换为数组赋值
  14.                 for (int y = 0; y < aDataInfo.Y.Length; y++)
  15.                 {
  16.                     for (int x = 0; x < aDataInfo.X.Length; x++)
  17.                     {
  18.                         dataResult[dataIndex] = ddt[y, x];

  19.                         dataIndex++;
  20.                     }
  21.                 }

  22.                 startdataArray[0] = mIndex;
  23.                 startdataArray[1] = dataIndex;
  24.                 startdataArray[2] = 0;
  25.                 startdataArray[3] = 0;

  26.                 countdataArray[0] = 1;
  27.                 countdataArray[1] = 1;
  28.                 countdataArray[2] = aDataInfo.Y.Length;
  29.                 countdataArray[3] = aDataInfo.X.Length;
  30.                 gridFile.WriteVara("SST_cpl", startdataArray, countdataArray, dataResult);
  31.             }         
复制代码
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2013-1-30 15:59:44 | 显示全部楼层
OK,搞定了。我这个数据不需要四维的数组。每个时间点的数据不一样就循环写12次。
每次写变量数据的时候把时间节点编码赋值给startArray[0].

以下附上本次内容的代码:
  1. NetCDFDataInfo aDataInfo = new NetCDFDataInfo();
  2.             string aFile = Application.StartupPath + "\\Sample\\Hadisst_obs_1949-2010_T106_BCC_AGCM2.1.nc";
  3.             //读取nc文件
  4.             aDataInfo.ReadDataInfo(aFile);

  5.             var t = aDataInfo.times;

  6.             List<GridData>[] datas = new List<GridData>[12];
  7.             int sYear = aDataInfo.times[0].Year;
  8.             int eYear = aDataInfo.times[aDataInfo.times.Count - 1].Year;
  9.             int yIndex = 0;
  10.             GridData gData = new GridData();
  11.             //循环年份
  12.             for (int startYear = 1961; startYear < eYear; startYear++)
  13.             {
  14.                 yIndex = startYear - sYear;

  15.                 //将每年12个月的数据都摆在相应月份的数组里
  16.                 for (int mIndex = 0; mIndex < 12; mIndex++)
  17.                 {
  18.                     List<GridData> mList = datas[mIndex];

  19.                     if (mList == null)
  20.                     {
  21.                         mList = new List<GridData>();
  22.                     }

  23.                     mList.Add(aDataInfo.GetGridData_LonLat(yIndex * 12 + mIndex, 3, 0));

  24.                     datas[mIndex] = mList;
  25.                 }
  26.             }

  27.             GridData[] mdatas = new GridData[12];

  28.             //对每个月份的数据计算平均值
  29.             for (int mIndex = 0; mIndex < 12; mIndex++)
  30.             {
  31.                 List<GridData> mList = datas[mIndex];

  32.                 mdatas[mIndex] = DataMath.Average(mList, false);
  33.             }

  34.             NetCDFDataInfo gridFile = new NetCDFDataInfo();
  35.             string outFilePath = Application.StartupPath + "\\Sample\\result.nc";
  36.             gridFile.fileName = outFilePath;
  37.             gridFile.UNDEF = aDataInfo.UNDEF;
  38.             gridFile.unlimdimid = aDataInfo.unlimdimid;

  39.             // Add dimensions:
  40.             foreach (var dimension in aDataInfo.dimList)
  41.             {
  42.                 gridFile.AddDimension(dimension);
  43.             }

  44.             object[] lonDatas = new object[160];
  45.             object[] latDatas = new object[320];

  46.             // Add variables
  47.             foreach (Variable variable in aDataInfo.varList)
  48.             {
  49.                 gridFile.AddVariable((Variable)variable.Clone());

  50.                 //Add variable attributes
  51.                 foreach (var attribute in variable.Attributes)
  52.                 {
  53.                     gridFile.AddVariableAttribute(variable.Name, attribute.attName, attribute.attValue.ToString());
  54.                 }

  55.                 if (variable.Name == "lon")
  56.                 {
  57.                     aDataInfo.GetVarData(variable, ref lonDatas);
  58.                 }

  59.                 if (variable.Name == "lat")
  60.                 {
  61.                     aDataInfo.GetVarData(variable, ref latDatas);
  62.                 }
  63.             }

  64.             //Add global attributes
  65.             foreach (var globalAttribute in aDataInfo.gAttList)
  66.             {
  67.                 gridFile.AddGlobalAttribute(globalAttribute.attName, globalAttribute.attValue.ToString());
  68.             }

  69.             //Create netCDF file
  70.             gridFile.CreateNCFile(outFilePath);

  71.             gridFile.WriteVar("lon", lonDatas);
  72.             gridFile.WriteVar("lat", latDatas);

  73.             int[] startArray = new int[1];
  74.             int[] countArray = new int[1];
  75.             double[] dataArray = new double[12];

  76.             for (int mIndex = 0; mIndex < 12; mIndex++)
  77.             {
  78.                 dataArray[mIndex] = mIndex;
  79.             }

  80.             startArray[0] = 0;
  81.             countArray[0] = 12;
  82.             gridFile.WriteVara("time", startArray, countArray, dataArray);


  83.             //创建一个可以盛放12个月数据的数组(从这个地方开始就不知道对不对了)
  84.             double[] dataResult = new double[aDataInfo.X.Length * aDataInfo.Y.Length];


  85.             //Add Data
  86.             int[] startdataArray = new int[3];
  87.             int[] countdataArray = new int[3];

  88.             //循环12个月的数据
  89.             for (int mIndex = 0; mIndex < 12; mIndex++)
  90.             {
  91.                 dataResult = new double[aDataInfo.X.Length * aDataInfo.Y.Length];
  92.                 int dataIndex = 0;
  93.                 //获取每个月的数据
  94.                 var ddt = mdatas[mIndex].Data;

  95.                 //将每个月的数据转换为数组赋值
  96.                 for (int y = 0; y < aDataInfo.Y.Length; y++)
  97.                 {
  98.                     for (int x = 0; x < aDataInfo.X.Length; x++)
  99.                     {
  100.                         dataResult[dataIndex] = ddt[y, x];

  101.                         dataIndex++;
  102.                     }
  103.                 }

  104.                 startdataArray[0] = mIndex;
  105.                 startdataArray[1] = 0;
  106.                 startdataArray[2] = 0;

  107.                 countdataArray[0] = 1;
  108.                 countdataArray[1] = aDataInfo.Y.Length;
  109.                 countdataArray[2] = aDataInfo.X.Length;
  110.                 gridFile.WriteVara("SST_cpl", startdataArray, countdataArray, dataResult);
  111.             }         
  112.             
  113.             gridFile.CloseNCFile();
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-1-31 07:29:59 | 显示全部楼层
搂主还是下了功夫的,通过写这个小程序应该对NetCDF格式有了更深入的理解。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2013-1-31 10:16:54 | 显示全部楼层
呵呵,对于netCDF格式文件终于从听说转变成知道了。
以后还要继续努力,加紧学习啊。感谢王老师的指导。
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表