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

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 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秒左右。

目录
相关文章
|
3月前
|
自然语言处理 数据可视化 API
淘宝商品评论 API 接口:深度解析用户评论,优化产品与服务
淘宝是领先的中国电商平台,其API为开发者提供商品信息、交易记录及用户评价等数据访问服务。对于获授权的开发者和商家,可通过申请API权限、获取并解析评论数据来进行情感分析和统计,进而优化产品设计、提升服务质量、增强用户互动及调整营销策略。未授权用户可能受限于数据访问。
|
2天前
|
存储 分布式计算 Java
存算分离与计算向数据移动:深度解析与Java实现
【11月更文挑战第10天】随着大数据时代的到来,数据量的激增给传统的数据处理架构带来了巨大的挑战。传统的“存算一体”架构,即计算资源与存储资源紧密耦合,在处理海量数据时逐渐显露出其局限性。为了应对这些挑战,存算分离(Disaggregated Storage and Compute Architecture)和计算向数据移动(Compute Moves to Data)两种架构应运而生,成为大数据处理领域的热门技术。
13 2
|
21天前
|
存储 固态存储 安全
阿里云服务器X86计算架构解析与X86计算架构云服务器收费价格参考
阿里云服务器架构分为X86计算、Arm计算、高性能计算等多种架构,其中X86计算是用户选择最多的一种架构,本文将深入探讨阿里云X86计算架构的云服务器,包括其技术特性、适用场景、性能优势以及最新价格情况。
|
22天前
|
编解码 弹性计算 应用服务中间件
阿里云服务器Arm计算架构解析:Arm计算架构云服务器租用收费标准价格参考
阿里云服务器架构分为X86计算、Arm计算、高性能计算等多种架构,其中Arm计算架构以其低功耗、高效率的特点受到广泛关注。本文将深入解析阿里云Arm计算架构云服务器的技术特点、适用场景以及包年包月与按量付费的收费标准与最新活动价格情况,以供选择参考。
|
3月前
|
机器学习/深度学习 算法 数据库
阿里云服务器架构区别解析:从X86计算、Arm计算到高性能计算架构的区别参考
在我们选择阿里云服务器的架构时,选择合适的云服务器架构对于提升业务效率、保障业务稳定至关重要。阿里云提供了多样化的云服务器架构选择,包括X86计算、ARM计算、GPU/FPGA/ASIC、弹性裸金属服务器以及高性能计算等。本文将深入解析这些架构的特点、优势及适用场景,以供参考和选择。
阿里云服务器架构区别解析:从X86计算、Arm计算到高性能计算架构的区别参考
|
2月前
|
KVM 虚拟化
计算虚拟化之CPU——qemu解析
【9月更文挑战10天】本文介绍了QEMU命令行参数的解析过程及其在KVM虚拟化中的应用。展示了QEMU通过多个`qemu_add_opts`函数调用处理不同类型设备和配置选项的方式,并附上了OpenStack生成的一个复杂KVM参数实例。
|
2月前
|
测试技术 UED 开发者
软件测试的艺术:从代码审查到用户反馈的全景探索在软件开发的宇宙中,测试是那颗确保星系正常运转的暗物质。它或许不总是站在聚光灯下,但无疑是支撑整个系统稳定性与可靠性的基石。《软件测试的艺术:从代码审查到用户反馈的全景探索》一文,旨在揭开软件测试这一神秘面纱,通过深入浅出的方式,引领读者穿梭于测试的各个环节,从细微处着眼,至宏观视角俯瞰,全方位解析如何打造无懈可击的软件产品。
本文以“软件测试的艺术”为核心,创新性地将技术深度与通俗易懂的语言风格相结合,绘制了一幅从代码审查到用户反馈全过程的测试蓝图。不同于常规摘要的枯燥概述,这里更像是一段旅程的预告片,承诺带领读者经历一场从微观世界到宏观视野的探索之旅,揭示每一个测试环节背后的哲学与实践智慧,让即便是非专业人士也能领略到软件测试的魅力所在,并从中获取实用的启示。
|
3月前
|
存储 数据挖掘 大数据
深度解析Hologres计算资源配置:如何根据业务场景选择合适的计算类型?
【8月更文挑战第22天】Hologres是一款由阿里云提供的分布式分析型数据库,支持高效的大数据处理与分析。本文通过电商优化商品推荐策略的案例,介绍了Hologres中的计算组型与通用型配置。计算组型提供弹性扩展资源,适合大规模数据及高并发查询;通用型则适用于多数数据分析场景,具备良好计算性能。通过实例创建、数据加载、计算任务建立及结果查询的步骤展示,读者可理解两种配置的差异并根据业务需求灵活选择。
52 2
|
4月前
|
存储 分布式计算 DataWorks
MaxCompute产品使用合集之如何在代码中解析File类型的文件内容
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
74 11
|
4月前
|
数据采集 供应链 监控
ERP系统中的库存周转率计算与优化解析
【7月更文挑战第25天】 ERP系统中的库存周转率计算与优化解析
137 0

推荐镜像

更多