ENVI_IDL:读取所有OMI产品的NO2柱含量并计算月均值、季均值、年均值+解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: ENVI_IDL:读取所有OMI产品的NO2柱含量并计算月均值、季均值、年均值+解析

1. 实验内容

这里我就不写第三周的课后作业,直接连着这个实验一起写了。



整体思路:

1. 获取Lon、Lat、NO2数据集的数据并对NO2数据做一些处理(填充值处理、单位换算、南北极调换)

2. 求和并计数

3. 求均值


2. 知识储备

由于OMI产品是HDF5文件,需要使用HDF5的相关函数,另外还会使用一些文件处理的函数。

获取HDF5数据的一般步骤:

1. 打开HDF5文件,获取文件id(使用h5f_open()函数)

2. 获取数据集名称(这里你可以通过编程,但是实在没有必要,使用HDF Explorer软件可以查看数据集、属性、还可以查看各个内容数据等,甚至可视化数据)

3. 通过数据集名称以及前面获取的文件id获取数据集的id(通过h5d_open()函数)

4. 获取数据集的数据(通过h5d_read()函数)

5. 关闭数据集和文件(通过h5f_close()、h5d_close()函数)

      1、打开HDF5文件,获取文件id

      2、获取数据集名

      3、将数据集名转换为数据集id

      4、从数据集id处读取数据

      5、关闭数据集和文件


3. 编程

function get_hdf5_ds, file_path, ds_name
  ; 构建函数: 获取数据集的数据
  ; 获取数据集所在文件的id
  file_id = h5f_open(file_path)
  ; 传入数据集所在文件的路径
  ; 获取数据集的id
  ds_id = h5d_open(file_id, ds_name)
  ; 传入数据集所在文件的id, 传入数据集的名称
  ; 获取数据集的数据
  ds_data = h5d_read(ds_id)
  ; 传入数据集的id
  ; 关闭数据集以及文件
  h5d_close, ds_id
  h5f_close, file_id
  ; 返回获取数据集的数据
  return, ds_data
end
pro week_three_test
  start = systime(1)
  ; 计算NO2的月均值、季均值、年均值,并以Geotiff格式输出、输出单位是mol/km2.
  ; 要求:程序需要一次完成所有均值的计算
  ; 所有文件的路径
  in_path = 'D:/IDL_program/experiment_data/chapter_2/NO2'
  ; 输出文件的路径
  out_path = 'D:/IDL_program/experiment_data/chapter_2/NO2/output/'
  if file_test(out_path, /directory) eq 0 then begin  ; 检查该目录是否存在, 不存在则创建
    file_mkdir, out_path
  endif
  ; 数据集所在group在文件中的路径
  group_path = '/HDFEOS/GRIDS/ColumnAmountNO2/Data Fields/'  ; 这里使用\后面会报错,应该使用/
  ; 数据集的名称
  ds_name = 'ColumnAmountNO2TropCloudScreened'
  ; 数据集在文件中的路径
  ds_path = group_path + ds_name
  ; 获取in_path内所有文件的路径
  file_path_array = file_search(in_path, '*.he5', count=file_count)  ; count=文件数目
  ; 从每一个文件路径获取文件名称
  file_name_array = file_basename(file_path_array, '.he5')
  ; 从文件名称中获取该文件的年份
  file_year_array = fix(strmid(file_name_array, 19, 4))
  ; 获取起始年份以及年份数
  start_year = min(file_year_array)
  end_year = max(file_year_array)
  year_count = end_year - start_year + 1
  ; 各种数据初始化
  ; 存储月份数据集初始化
  data_total_month = fltarr(1440, 720, 12)  ; 每一个数据集都是(1440, 720), 一年有十二个月份
  data_valid_month = fltarr(1440, 720, 12)  ; 有的数据集上的NO2数据是无效的,那么我们求平均就不是/ 12,而是看有几次有效次数了
  data_aver_month = fltarr(1440, 720, 12)  ; 上面的data_total_month / data_valid_month即可得到
  ; 存储季节数据集的初始化
  data_total_season = fltarr(1440, 720, 4)  ; 一年4季
  data_valid_season = fltarr(1440, 720, 4)  ; 有效次数
  data_aver_season = fltarr(1440, 720, 4)  ; 平均值
  ; 存储年数据集的初始化
  data_total_year = fltarr(1440, 720, year_count)  ; 一共有year_count年
  data_valid_year = fltarr(1440, 720, year_count)
  data_aver_year = fltarr(1440, 720, year_count)
  ; 进入循环
  for file_i = 0, file_count - 1 do begin
    ; 检查该文件的NO2数据集是否存在
    flag = 0
    file_path = file_path_array[file_i]  ; 获取该循环下的文件路径
    file_id = h5f_open(file_path)  ; 获取文件id
    ds_count = h5g_get_nmembers(file_id, group_path)  ; 传入文件id以及group路径返回该group下的数据集个数
    for ds_i = 0, ds_count - 1 do begin
      ds_i_name = h5g_get_member_name(file_id, group_path, ds_i)
      if ds_i_name eq ds_name then begin
        flag = 1
        continue
      endif
    endfor
    if flag ne 0 then begin
      ; 提示该文件存在数据集
      print, 'Exit NO2 data set>>> ' + file_basename(file_path)
      ; 根据文件的名称得到该文件的年月日
      file_year = fix(strmid(file_basename(file_path), 19, 4))
      file_month = fix(strmid(file_basename(file_path), 24, 2))
      ; 获取数据集的数据
      ds_data = get_hdf5_ds(file_path, ds_path)
      ; 填充值处理
      ds_data = (ds_data gt 0) * ds_data  ; 负数(填充值)变成0
      ; 单位换算(分子数/cm2 ————》mol/km2)
      ds_data = (ds_data * 10.0 ^ 10.0) / !const.NA
      ; 将南北极位置调换
      ds_data = rotate(ds_data, 7)
      ; 存储数据集————》月
      data_total_month[*, *, file_month - 1] = data_total_month[*, *, file_month - 1] + ds_data
      data_valid_month[*, *, file_month - 1] = data_valid_month[*, *, file_month - 1] + (ds_data gt 0)
      ; 存储数据集————》季
      season_index = [3, 3, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3]
      data_total_season[*, *, season_index[file_month - 1]] = data_total_season[*, *, season_index[file_month - 1]] + ds_data
      data_valid_season[*, *, season_index[file_month - 1]] = data_valid_season[*, *, season_index[file_month - 1]] + (ds_data gt 0)
      ; 存储数据集————》年
      data_total_year[*, *, file_year - start_year] = data_total_year[*, *, file_year - start_year] + ds_data
      data_valid_year[*, *, file_year - start_year] = data_valid_year[*, *, file_year - start_year] + (ds_data gt 0)
    endif else begin
      print, 'Not exit NO2 data set>> ' + file_basename(file_path)
    endelse
  endfor
  ; 年月日的数据集的均值处理
  ; 月处理
  data_valid_month = (data_valid_month gt 0) * data_valid_month + (data_valid_month eq 0) * 1.0
  data_aver_month = data_total_month / data_valid_month
  ; 季处理
  data_valid_season = (data_valid_season gt 0) * data_valid_season + (data_valid_month eq 0) * 1.0
  data_aver_season = data_total_season / data_valid_season
  ; 年处理
  data_valid_year = (data_valid_year gt 0) * data_valid_year + (data_valid_year eq 0) * 1.0
  data_aver_year = data_total_year / data_valid_year
  ; geotiff设置
  geoinfo = {$
    MODELPIXELSCALETAG:[0.25,0.25,0.0],$
    MODELTIEPOINTTAG:[0.0,0.0,0.0,-180.0,90.0,0.0],$
    GTMODELTYPEGEOKEY:2,$
    GTRASTERTYPEGEOKEY:1,$
    GEOGRAPHICTYPEGEOKEY:4326,$
    GEOGCITATIONGEOKEY:'GCS_WGS_1984',$
    GEOGANGULARUNITSGEOKEY:9102,$
    GEOGSEMIMAJORAXISGEOKEY:6378137.0,$
    GEOGINVFLATTENINGGEOKEY:298.25722}
  ; 输出设置
  month_out = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']
  season_out = ['spring', 'summer', 'autumn', 'winter']
  ; 依次输出月、季、年均值
  for month_i = 0, 11 do begin
    out_month_path = out_path + 'month_aver_' + month_out[month_i] + '.tiff'
    write_tiff, out_month_path, data_aver_month[*, *, month_i], /float, geotiff=geoinfo
    print, file_basename(out_month_path) + ' have completed'
  endfor
  for season_i = 0, 3 do begin
    out_season_path = out_path + 'season_aver_' + month_out[season_i] + '.tiff'
    write_tiff, out_season_path, data_aver_season[*, *, season_i], /float, geotiff=geoinfo
    print, file_basename(out_season_path) + ' have completed'
  endfor
  for year_i = 0, year_count - 1 do begin
    out_year_path = out_path + 'year_aver_' + strcompress(string(year_i + start_year), /REMOVE_ALL) + '.tiff'
    write_tiff, out_year_path, data_aver_year[*, *, year_i], /float, geotiff=geoinfo
    print, file_basename(out_year_path) + ' have completed'
  endfor
  ; 这里再将年结果输出为txt文件
  out_txt_path = out_path
  for year_i = 0, year_count - 1 do begin
    out_year_path = out_txt_path + 'year_aver_' + strcompress(string(year_i + start_year), /REMOVE_ALL) + '.txt'
    openw, 2, out_year_path
    printf, 2, 'lon lat NO2'
    ; 每一个像元的最中心,一个像元是0.25*0.25
    for row_i = 0, 719 do begin
      lat = 89.875 - 0.25 * row_i  
      for column_i = 0, 1439 do begin
        lon = -179.875 + column_i * 0.25
        printf, 2, lon, lat, data_aver_year[column_i, row_i, year_i], format='(3(f0.3, :, ","))'
      endfor
    endfor
    print, file_basename(out_year_path) + ' have completed'
    free_lun, 2
  endfor
  stop = systime(1)
  print, 'Spend time : ' + strcompress(string(stop - start))
end


编译运行结果展示:



生成的tiff文件展示:



使用ENVI打开确实没有问题:



另外需要说一点,这里报错,浮点数非法!但是貌似不影响结果的输出。

虽然但是,我还是心情不舒服。

还有一点就是前面的tiff文件输出是比较快的,但是最后面的txt文件输出很慢,我差点都以为没有运行成功,报时91秒左右。

目录
相关文章
|
1月前
|
机器学习/深度学习 自然语言处理 搜索推荐
自注意力机制全解析:从原理到计算细节,一文尽览!
自注意力机制(Self-Attention)最早可追溯至20世纪70年代的神经网络研究,但直到2017年Google Brain团队提出Transformer架构后才广泛应用于深度学习。它通过计算序列内部元素间的相关性,捕捉复杂依赖关系,并支持并行化训练,显著提升了处理长文本和序列数据的能力。相比传统的RNN、LSTM和GRU,自注意力机制在自然语言处理(NLP)、计算机视觉、语音识别及推荐系统等领域展现出卓越性能。其核心步骤包括生成查询(Q)、键(K)和值(V)向量,计算缩放点积注意力得分,应用Softmax归一化,以及加权求和生成输出。自注意力机制提高了模型的表达能力,带来了更精准的服务。
|
6天前
|
弹性计算 运维 网络安全
阿里云轻量应用服务器产品解析与搭建个人博客网站教程参考
轻量应用服务器(Simple Application Server)作为阿里云面向单机应用场景推出的云服务器产品,以其一键部署、一站式管理、高性价比等特性,深受个人开发者、中小企业及入门级用户的喜爱。本文将全面解析阿里云轻量应用服务器的产品优势、应用场景、使用须知,以及使用轻量应用服务器搭建个人博客网站的详细教程,帮助用户更好地了解和使用这一产品。
|
6月前
|
自然语言处理 数据可视化 API
淘宝商品评论 API 接口:深度解析用户评论,优化产品与服务
淘宝是领先的中国电商平台,其API为开发者提供商品信息、交易记录及用户评价等数据访问服务。对于获授权的开发者和商家,可通过申请API权限、获取并解析评论数据来进行情感分析和统计,进而优化产品设计、提升服务质量、增强用户互动及调整营销策略。未授权用户可能受限于数据访问。
|
2月前
|
缓存 网络协议 安全
融合DNS技术产品和生态
本文介绍了阿里云在互联网基础资源领域的最新进展和解决方案,重点围绕共筑韧性寻址、赋能新质生产展开。随着应用规模的增长,基础服务的韧性变得尤为重要。阿里云作为互联网资源的践行者,致力于推动互联网基础资源技术研究和自主创新,打造更韧性的寻址基础服务。文章还详细介绍了浙江省IPv6创新实验室的成立背景与工作进展,以及阿里云在IPv6规模化部署、DNS产品能力升级等方面的成果。此外,阿里云通过端云融合场景下的企业级DNS服务,帮助企业构建稳定安全的DNS系统,确保企业在数字世界中的稳定运行。最后,文章强调了全链路极致高可用的企业DNS解决方案,为全球互联网基础资源的创新提供了中国标准和数字化解决方案。
|
2月前
|
存储 搜索推荐 数据挖掘
投资回报与预算考量:CRM产品报价全解析
在当今竞争激烈的商业环境中,CRM系统已成为企业不可或缺的工具。它能有效管理客户信息、提升销售效率、优化服务并增强忠诚度。选择合适的CRM需考虑功能、用户数量、定制需求、技术支持及数据安全等因素,确保在预算内实现最大价值。企业在挑选时应明确需求、比较产品、评估长期回报,并考虑扩展性。最适合自己业务需求的CRM才是最佳选择。
|
3月前
|
存储 分布式计算 Java
存算分离与计算向数据移动:深度解析与Java实现
【11月更文挑战第10天】随着大数据时代的到来,数据量的激增给传统的数据处理架构带来了巨大的挑战。传统的“存算一体”架构,即计算资源与存储资源紧密耦合,在处理海量数据时逐渐显露出其局限性。为了应对这些挑战,存算分离(Disaggregated Storage and Compute Architecture)和计算向数据移动(Compute Moves to Data)两种架构应运而生,成为大数据处理领域的热门技术。
142 2
|
4月前
|
存储 固态存储 安全
阿里云服务器X86计算架构解析与X86计算架构云服务器收费价格参考
阿里云服务器架构分为X86计算、Arm计算、高性能计算等多种架构,其中X86计算是用户选择最多的一种架构,本文将深入探讨阿里云X86计算架构的云服务器,包括其技术特性、适用场景、性能优势以及最新价格情况。
|
4月前
|
编解码 弹性计算 应用服务中间件
阿里云服务器Arm计算架构解析:Arm计算架构云服务器租用收费标准价格参考
阿里云服务器架构分为X86计算、Arm计算、高性能计算等多种架构,其中Arm计算架构以其低功耗、高效率的特点受到广泛关注。本文将深入解析阿里云Arm计算架构云服务器的技术特点、适用场景以及包年包月与按量付费的收费标准与最新活动价格情况,以供选择参考。
|
5月前
|
KVM 虚拟化
计算虚拟化之CPU——qemu解析
【9月更文挑战10天】本文介绍了QEMU命令行参数的解析过程及其在KVM虚拟化中的应用。展示了QEMU通过多个`qemu_add_opts`函数调用处理不同类型设备和配置选项的方式,并附上了OpenStack生成的一个复杂KVM参数实例。
|
5月前
|
测试技术 UED 开发者
软件测试的艺术:从代码审查到用户反馈的全景探索在软件开发的宇宙中,测试是那颗确保星系正常运转的暗物质。它或许不总是站在聚光灯下,但无疑是支撑整个系统稳定性与可靠性的基石。《软件测试的艺术:从代码审查到用户反馈的全景探索》一文,旨在揭开软件测试这一神秘面纱,通过深入浅出的方式,引领读者穿梭于测试的各个环节,从细微处着眼,至宏观视角俯瞰,全方位解析如何打造无懈可击的软件产品。
本文以“软件测试的艺术”为核心,创新性地将技术深度与通俗易懂的语言风格相结合,绘制了一幅从代码审查到用户反馈全过程的测试蓝图。不同于常规摘要的枯燥概述,这里更像是一段旅程的预告片,承诺带领读者经历一场从微观世界到宏观视野的探索之旅,揭示每一个测试环节背后的哲学与实践智慧,让即便是非专业人士也能领略到软件测试的魅力所在,并从中获取实用的启示。

热门文章

最新文章

推荐镜像

更多