卫星碳监测这几年越来越热,但真正动手做过的人都知道,最卡人的往往不是反演算法本身,而是“怎么拿到一套能直接拿来用的全球XCO₂浓度场”。GOSAT和OCO-2都是公开数据,但这俩传感器的采样方式、重访周期、反演版本全都不一样,你下载下来之后面对的是几千个离散footprint,不是一张能直接画图的全球浓度场。
全球1° XCO₂浓度栅格数据集(2009–2020,融合GOSAT+OCO-2卫星,日尺度+月尺度,GeoTIFF格式)这类产品,就是把脏活累活做掉之后交付的标准输入。这篇文章不打算念产品说明书,我重点讲清楚这套数据背后的融合逻辑、拿到手之后怎么处理、以及用的时候最容易翻车的几个细节。无论你是做碳源汇反演、大气传输模拟,还是单纯需要一张全球XCO₂图放到论文里做背景场,这篇都值得看完。
1. 这套数据集到底解决什么问题:从卫星“条带”到全球“拼图”
1.1 为什么直接用GOSAT和OCO-2的观测不够用
先明确一个概念:卫星反演出来的XCO₂,指的是大气柱平均干空气二氧化碳干空气摩尔分数,单位一般是ppm。GOSAT和OCO-2的原始产品都是“footprint”级别的离散点,每个footprint是一个椭圆光斑或者沿轨扫描的窄条,覆盖范围从几平方公里到几十平方公里不等。单颗卫星每天能拿到的有效观测点,听起来很多,但放到全球来看,稀疏程度相当感人。
如果你直接拿这些离散点画全球图,会得到一张全是孔的图。陆地上有数据,海洋上数据少得多;中纬度地区相对密,赤道对流云多的地方经常整片缺测;极地冬半年太阳高度角太低或者没有光照,基本停摆。更麻烦的是,GOSAT和OCO-2的轨道设计、当地时间过境时刻、扫描模式都不一样,简单混在一起用,浓度场会被时间和空间采样的不均匀性扭曲。
这就是为什么需要做“网格化”和“融合”的原因。网格化把散点变成规则格网,融合把多颗卫星的信息合并成一个自洽的浓度场。你拿到手的1°栅格,本质上不是“观测直接填进去的”,而是经过空间插值、时间滤波、多源加权之后的重建场。
1.2 1°栅格 + 日/月双尺度的设计逻辑
1°分辨率大约在赤道对应111公里左右,在中纬度经度方向会窄一些,但大体是百公里量级。这个尺度对全球碳循环研究来说是一个很微妙的平衡点:太细了,卫星观测密度撑不住,插值出来全是插值假象;太粗了,区域输送和局地源汇信号被抹平,没法做区域分析。
日尺度数据用来保留天气尺度的变化。XCO₂不是静止的,大气输送会把高浓度区往顺风方向拖出长条,天气系统的移动也会造成浓度场快速变化。逐日产品能让你看到这种动力过程,但代价是单日覆盖不完整、噪声较大,很多像元只能靠前后时间窗来补。
月尺度数据则是给“气候态”分析准备的。一个月积累下来的观测足够覆盖大部分区域,月平均过程能把反演噪声和短时间天气波动压下去,信噪比高很多。做季节循环、年际趋势、区域对比,几乎都应以月尺度为准。这套数据集同时给了日尺度和月尺度,就是让你自己按场景去选,不要拿一天的图去做趋势,也不要用月均值去追一次天气过程。
1.3 融合两类传感器的难点在哪里
融合GOSAT和OCO-2绝不是“把两组散点倒进一个桶里取平均”那么简单。难点在三个层面。
第一,系统偏差。GOSAT和OCO-2虽然都测XCO₂,但反演光谱波段、气溶胶处理、散射订正算法不完全一致,两者在同一时间同一地点测出来的值经常有零点几ppm的系统差异。这个差异看着小,但碳源汇反演对背景场的精度要求已经到了亚ppm级别,必须做偏差订正。
第二,信息权重不同。GOSAT是光栅型传感器,footprint大,对整层大气的观测更“平滑”;OCO-2是光栅光谱仪,空间分辨率更高,对局地信号更敏感。两者的观测误差协方差结构完全不一样,融合时得按误差大小分配权重,而不是平均对待。
第三,稀疏观测条件下的代表性误差。卫星像元是一根“柱子”的积分浓度,1°格网里的观测点可能分布在格网边缘甚至跨越地形差异大的区域,山地、海岸线附近的代表性误差会明显增大。融合算法必须考虑这些因素,否则做出的场会在某些区域出现不自然的梯度。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 数据源与融合思路:GOSAT、OCO-2各自的家底和脾气
2.1 GOSAT:温室气体观测的“老黄牛”
GOSAT(Ibuki)是2009年发射的,搭载TANSO-FTS干涉仪,在CO₂和CH₄观测领域算是开山鼻祖。它的设计目标是全球尺度的柱浓度观测,footprint直径大约10公里上下,在轨扫描模式能覆盖较宽的跨轨范围。优点是资料序列长、覆盖连续,缺点也很明显:空间分辨率偏低,对城市、点源这类局地信号不够敏感。
2009到2020这个时间段正好覆盖了GOSAT的全生命周期主体。作为时间序列最长的温室气体卫星,它是这套数据集里“定基调”的角色——年头早的时段,全球高覆盖连续观测基本只能靠它。GOSAT反演产品有不同版本(如不同机构发布的NIES、ACOS版本),不同版本之间也存在差异,数据集制作方通常需要选定一个主产品版本,再对另一颗卫星做统一化处理。
2.2 OCO-2:高精度但“挑剔”的扫描仪
OCO-2是2014年发射的,目标明确:提升XCO₂的测量精度和空间分辨率,支持碳源汇研究。它沿轨获取狭长的光谱条带,空间分辨率比GOSAT高不少,信噪比也更好,对区域浓度梯度和局地源汇的分辨能力明显更强。但OCO-2的刈幅很窄,覆盖密度并没有因为分辨率高而变成“密网”,它更像一把精细的手术刀,而不是一张大网。
2014年以后,OCO-2的加入让整个数据集的精度上限提高了。典型的处理套路是:先以GOSAT长序列重建一个相对平滑的全球背景场,再引入OCO-2的高精度信息对背景场进行修正。这样做既保留了时间连续性,又吸收了高分辨率观测的优势。
2.3 融合方法选型:为什么要走“两段式”而不是直接平均
如果只是把两颗卫星的数据拼起来取平均,时间上分层的系统偏差和空间上不均匀的信息密度会直接破坏产品一致性。更合理的思路是两段式处理:先做“观测偏差校正”,再做“时空插值与数据融合”。
偏差校正这一步,通常需要找一个“基准”,比如TCCON地面站网的观测值,或者某一颗偏差特征更明确的卫星产品。把GOSAT和OCO-2分别和基准对比,拟合出偏差随纬度、季节、气溶胶条件、观测几何等因素变化的函数,然后把这个偏差从原始反演值里去掉。这样两颗卫星的数值系统就被拉到了同一个“标尺”上。
偏差校正完以后,就可以用最优插值(OI)、克里金或者变分方法把多源观测融合到规则格网上。这类方法的共同逻辑是:不是让观测值直接等于格点值,而是让最终场在满足观测值约束的前提下尽量平滑,同时根据每个观测点的误差协方差决定它对周围格点的影响范围。简单说,观测误差小的点,影响半径大、权重高;观测误差大的点,只影响它附近很小范围。
2.4 时空归一化:所有卫星数据融合前必须做的一步
很多人容易忽略的是空间代表性和时间窗口的归一化。卫星观测是瞬间采样,不同轨道经过同一格网的时间可能差了几个小时,这几小时里大气的输送已经把浓度的空间形态改掉了。做日尺度融合时,要么只取一个较短的时间窗(例如以当地正午为中心±3小时),要么在插值算法里显式加上时间维度的协方差衰减。
另外,卫星反演的XCO₂有“先验依赖”,反演结果会向先验浓度场靠拢,尤其当地面信号弱、云污染多的时候。不同传感器使用的先验场不同,融合前如果不做去先验化处理,最终产品里会残留源传感器的“气质”。这一点论文里经常只提一句“we use the ACOS XCO₂ dataset”,但实操中处理不当,后期的全球图里会出现和天气过程无关的“纹理”。
3. 拿到GeoTIFF后的第一步:读取、探查与一图流出图
3.1 用Python快速读取栅格
这套数据集是GeoTIFF格式,意味着它自带地理参考信息,不需要你另外配一个单独的坐标文本文件。用Python处理GeoTIFF最顺手的选择是rasterio,或者更底层的GDAL。如果你只做简单读取,rasterio几行代码就能把数据和地理信息一起取出来。
python复制import rasterio
import numpy as np
path = "xco2_2015_06_monthly_1deg.tif"
with rasterio.open(path) as src:
data = src.read(1) # 第一波段
transform = src.transform
crs = src.crs
nodata = src.nodata
meta = src.meta
print(crs, transform, nodata, data.shape)
这里有两个小点要提醒。第一,data.shape是(行, 列),对应的是纬度从北到南还是从南到北,完全取决于文件里怎么写,不要想当然认为第一行就是北纬90度。第二,nodata值的处理必须放在第一步,很多算法在后期遇到异常大值或者异常小值,源头就是没先做无效值掩膜。
3.2 坐标系、像元大小和无效值:三个最容易踩坑的地方
这套数据的坐标系通常直接用经纬度(EPSG:4326),因为全球1°网格用等经纬度网格最符合习惯。但你要清楚,等经纬度网格的像元在高纬度地区面积会被压缩,如果你要计算区域总量或者做面积加权平均,不能直接对所有像元一视同仁,必须乘cos(纬度)做权重。
像元大小也需要确认是“中心点坐标”还是“边界对齐”。有的GeoTIFF里第一个像元的中心是-89.5,有的则是边界从-90开始。差半个像元,提取站点对应值时偏差就可能到几十公里,对于碳浓度场这种空间相关性很强的变量,几十公里带来的浓度差异往往被低估。
无效值的定义也要看仔细,有的用-9999,有的用NaN,有的把有效范围之外的值填成-1。读取后先打印一下最小值、最大值、分位数,确认数据范围是否合理。XCO₂全球分布一般在385到410 ppm之间(2009到2020年),如果出现几百或者几千的极端值,基本就是无效值没处理好。
3.3 一图流出图与常用可视化库
拿到栅格后第一件有成就感的事就是画出来。常规做法是用matplotlib配cartopy,直接imshow加海岸线就够用。
python复制import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
mask = data == nodata
data_masked = np.ma.masked_where(mask, data)
fig = plt.figure(figsize=(12, 6))
ax = fig.add_subplot(111, projection=ccrs.PlateCarree())
im = ax.pcolormesh(data_masked, cmap='RdYlBu_r', vmin=388, vmax=404,
transform=ccrs.PlateCarree())
ax.add_feature(cfeature.COASTLINE, linewidth=0.5)
plt.colorbar(im, shrink=0.8, label='XCO2 (ppm)')
plt.title('Global XCO2 Monthly Mean')
plt.show()
要注意,pcolormesh传的是数据数组而不是经纬度网格时,范围默认按数组下标走,加上extent参数才能和地理坐标对齐。还有一点经验:全球图尽量别用imshow直接显示未掩膜的数组,因为陆地和海洋边界会把缺失区域也涂上颜色,误导视觉效果。
4. 日尺度与月尺度:数据在时间维度上的使用逻辑
4.1 日尺度数据:适合看动态过程,但别迷信细节
日尺度文件的价值在于看“演变”。一次气团输送事件、一个高压系统控制下的浓度堆积、一次季风爆发带来的清洁空气,都可以在逐日序列上看到。这时候你会明显感觉到XCO₂不是均匀混合的气体,它带着下垫面的信号被风拖着走。
但正因为是日尺度,单日覆盖度低,很多格点只能靠邻近日期插补出来。不要在单日图上解读某一个格点的“异常高值”,那个高值可能是插值产物,也可能是云污染残留。我的经验是,日尺度数据适合做“动画”或者“序列剖面”,不适合做“单点定论”。
如果你想做一个区域的日尺度时间序列,建议先设置一个最小有效覆盖条件,例如“当天该区域有效栅格占比超过30%才参与平均”,否则标记为缺测。这样能有效避免因为覆盖太少导致序列出现假跳变。
4.2 月尺度数据:区域对比和趋势分析的主力
月平均数据把一个月内所有有效观测和插值结果聚合起来,覆盖度大幅提升,信噪比也更好。做北半球和南半球的浓度差、做季节振幅、做年际增量,都应该以月尺度为主。
举个例子,要分析东亚地区XCO₂的季节循环,你提取每个月度文件里对应区域的面积加权平均值,得到一条12个月的曲线,然后叠加不同年份的曲线看季节振幅的变化。如果拿日尺度数据去画这个曲线,曲线会毛刺很多,尤其冬天中高纬度观测稀疏的时候,单日平均值非常不稳定。
4.3 时间插补与缺测处理:别一缺数就填零,也不要线性硬插
栅格数据在时间维度上同样会有缺测,特别是早年和某些高纬度冬季。处理时间序列缺测时,最忌讳的是“空值填0”,这会把浓度序列变成灾难。更合理的做法有几种:
- 线性插值,仅适用于短期缺测(比如连续缺1到3天);
- 气候态填补,用多年同月的平均值当作背景值,但会削弱异常信号,不适合做趋势分析;
- 不填补,直接在统计模型中当缺测处理,适合逐像元拟合趋势的场景。
我的建议是:趋势分析优先使用“不填补+稳健回归”,季节循环分析可以用多年月均值补,但务必备注哪些格点是实测插值得到的、哪些是气候态插补的。数据集本身如果有标记质量的波段,比如“有效观测计数”,一定要用起来,它比浓度值本身更能告诉你一个格点数据的可信度。
5. 实测验证和常见误区:从0.1 ppm级别的差异说起
5.1 拿TCCON地面站点做验证:方法不复杂但很关键
拿到数据集之后,第一步不是直接画全球图,而是先和TCCON地面站点做验证。TCCON(Total Carbon Column Observing Network)提供的地基FTS XCO₂观测精度很高,是公认的卫星验证基准。
做法很简单:把站点坐标落到栅格上,提取对应格点的月尺度浓度值,再和TCCON月均值对比,画散点图、算偏差和均方根误差。因为TCCON站点数量有限,对比结果不能代表全球,但足以给你一个信心判断——这个数据集在你的目标区域到底靠不靠谱。
这里有个细节:TCCON站点分布偏向北美和欧洲,东亚和南半球站点相对少。如果你的研究区正好是站点稀疏区,验证效果会打折扣,可以考虑用航空观测(如NEON/ATom这类资料)或者多套卫星产品做交叉对比,交叉对比不是找“谁对”,而是看“差异有多大”。
5.2 传感器之间的系统偏差:为什么换了卫星后均值会“跳”
一个非常典型的现象是:2014年之后,很多融合产品里北半球中纬度的平均浓度会出现一个“台阶”,尽管真实浓度是在缓慢上升的。这个跳变很多时候不是大气真的突变,而是GOSAT和OCO-2之间的系统偏差没被完全校正。
判断方法是把时间序列按“主传感器”分段来看:2009到2013年主要由GOSAT主导,2015年以后OCO-2加入甚至主导,如果分段拟合的残差在切换年份附近出现系统性偏移,说明偏差订正不彻底。做趋势分析时,建议把这种切换年份作为断点进行检验,不要硬用一条直线拟合跨越整个时间段的序列。
5.3 尺度上推和混合像元:1°格网里到底装着什么
1°格网是个大框子,里面可能有森林、农田、水体和城市。卫星footprint观测的是整个气柱,而这个气柱的空气在到达观测位置之前已经混合了前面几百上千公里的源汇信息,所以1°格网的浓度值并不是“这个格网的地面排放”直接决定的。
做区域对比时,不要试图把某个城市或者某个火山点源的信令从一个1°格网里单独拎出来,大概率拎不动。XCO₂的浓度梯度太缓,又经过大尺度混合,一个百公里尺度的格网值更多反映的是区域尺度(几百到上千公里)的信号。真想捕捉城市尺度的CO₂排放,用OCO-2的footprint或OCO-3的SnapShot模式更合适,而不是1°网格产品。
6. 用这套数据做研究时的实操建议与避坑清单
6.1 存储、命名与版本管理
GeoTIFF文件一个就几十上百MB,2009到2020年12年、日尺度加月尺度,累计文件数非常多。建议下载后第一时间整理目录结构,例如:
text复制data/
daily/2009/20090101_xco2_1deg.tif
monthly/2009/200901_xco2_1deg.tif
文件命名里包含时间标识、变量名、分辨率,是省心省钱的好习惯。做处理时,每产生一个中间文件就加一个后缀(_masked、_anom、_detrended),避免后面完全分不清哪个是原始数据哪个是加工产物。我后来吃了好几回亏,就是因为把原始文件和中间文件放在一起,某次清理磁盘时不小心删了原始栅格。
6.2 分区域、分季节的分析策略
全球平均的XCO₂浓度基本是稳步上升,这种信号谁都能画出来。真正有科学价值的是“差量”——相对于全球平均的异常、相对于季节循环的残差、南北半球不对称性的变化、海洋和陆地之间的对比。
建议把分析拆成几个维度:
- 纬度带:热带、北半球中纬度、南半球中纬度、极地分开统计;
- 季节:分别看DJF、MAM、JJA、SON的异常场;
- 区域:按大陆或者关键生物群区(亚马逊、东南亚热带林、北美作物带)提取区域序列。
每个维度都做“面积加权平均”,因为1°格网在高纬度过密,直接算术平均会让高纬度区域信号被过度放大。
6.3 把栅格提取成站点时间序列:代码思路
如果你不想要整张全球图,只想提取若干点位的浓度序列,可以用rasterio按经纬度索引。
python复制import rasterio
from rasterio.warp import transform_xy
lons = [116.4, 139.7, 10.1] # 示例站点经度
lats = [40.0, 35.7, 54.3] # 示例站点纬度
values = []
with rasterio.open("xco2_monthly_2015_06.tif") as src:
for lon, lat in zip(lons, lats):
col, row = ~src.transform * (lon, lat)
col, row = int(col), int(row)
val = src.read(1, window=((row-1, row+2), (col-1, col+2)))
# 取2x2窗口时需处理边界和无效值
values.append(float(np.nanmean(val[val != src.nodata])))
注意这段代码里做了一个2×2窗口平均,目的是减少单像元定位误差。如果站点刚好落在格网边界,直接取一个像元可能吃到相邻陆海格网的值,窗口平均更稳妥。
6.4 做脚注时值得补充的元数据信息
研究中使用这套数据时,需要写的“说明文字”不要偷懒。建议至少包含:
- 数据集的时间覆盖范围和空间分辨率;
- 原始卫星反演产品及版本号(例如GOSAT的某个级别产品、OCO-2的哪个版本);
- 融合算法的类型(最优插值、机器学习回归还是变分同化);
- 偏差订正的基准(TCCON或者其他参考场);
- 日尺度数据在局部区域的覆盖度限制;
- 月尺度数据对天气尺度扰动的时间平滑程度。
这些信息不仅是为了论文审稿人,更是为了你自己以后返工。数据集一旦过了一年再拿出来用,你是根本记不住当初怎么处理的,只有元数据能救命。
做这套数据集的融合和验证过程中,我自己最大的教训是:永远不要轻信“产品层级”的平滑外表。GeoTIFF文件看起来就是一张完整的全球图,但背后的覆盖度、系统偏差和插值痕迹,才是真正决定这张图能不能用的因素。建议你拿到数据后,第一周先别做任何漂亮的分析图,只做三件事:读文件、查覆盖度、和地面站比对。把这三件事做完,你对该数据集的脾气就摸得差不多了,之后再做任何科学分析,心里都有底。
