☰
RayManPro全流程:气象数据如何转成PET热舒适指标
2026/10/17 0:56:54 网站建设 项目流程

简介:RayManPro.zip 是一套基于 RayMan 模型的人体生理等效温度(PET)计算工具,面向城市气候、建筑环境与室外热舒适研究领域的科研人员、规划师及高校相关专业学生。通过输入云量、空气温度、相对湿度、风速等常规气象参数,并结合受测人群的年龄、性别、身高、体重、新陈代谢率、着装热阻及长短波辐射等个体特征,即可快速求解不同时空尺度下的 PET 值,为热环境评估与城市空间热舒适优化提供量化依据。压缩包为 zip 格式,整体体量约 1.26MB,便于本地部署与便携使用,适合在实地热环境监测数据整理、建筑外环境分析及热舒适对比研究中直接调用。目前已有 606 人浏览学习,反映出该工具在室外热舒适评价领域的实用价值。资源聚焦 RayMan 模型的核心计算流程与参数配置逻辑,有助于使用者系统掌握 PET 计算的完整操作路径,缩短建模与参数调试周期,是开展热环境实证研究或课程实验的有力辅助工具。

1. 做室外热舒适评价的人,手里基本都有同一个痛点:拿到的气象数据是云量、空气温度、相对湿度、风速,领导要的却是“这个广场夏天下午到底热不热”的量化结论。中间差的这一步,就是人体生理等效温度PET。RayManPro 就是把这四个气象参数完整转换成 PET 的工具包,平均辐射温度、太阳辐射、服装模型全部摊开给你看,不是黑匣子。下面直接讲从输入到输出的完整链路,重点放在参数怎么给不踩坑、批量模拟怎么跑、结果怎么验证。适合做城市设计、景观分析和建筑前期气候评估的工程师,也适合刚接触热舒适指标的研究生。

2. 从四个气象参数到PET:RayManPro的计算链路与输入边界

2.1 PET不是查表查出来的,是解人体能量平衡方程解出来的

PET这个指标很多人当它是查表出来的,其实它是反算出来的。先明确定义:在室外真实条件下,人体皮肤温度、核心温度达到某一状态,把这个状态搬到一个人工设定的标准室内环境中(通常风速0.1 m/s、相对湿度50%、室内辐射温度等于空气温度),室内气温需要调到多少度,人体才能恢复同样的热感觉,这个温度就是PET。所以PET的本质是通过人体热量平衡模型反算的等价温度,而不是像风寒温度那样套一个经验公式完事。

RayMan的计算链路大致有五步。第一步,按日期、当地时间、经纬度算太阳高度角和方位角,这一步决定短波辐射的基础入射量。第二步,用云量拆解逐时短波辐射:云量进入模型后控制直射和散射的比例,阴天直射接近零,全部变成散射。第三步,结合站点周围遮挡(建筑、树冠)和地表反照率,算人体表面的短波吸收和长波辐射交换,得到平均辐射温度Tmrt。第四步,把空气温度、相对湿度、风速、服装热阻、代谢率放进人体能量平衡方程,迭代解出皮肤温度和各项散热。第五步,把最终的人体热状态放到标准室内环境里反算室内气温,得到PET。

人体能量平衡方程的简化写法是 M+W = C+E+R+S。左边是代谢产热M和机械功W,右边是对流散热C、蒸发散热E、辐射换热R和蓄热S,稳态下S=0。RayMan在迭代里反复调节皮肤温度和服装表面温度,直到方程收敛。PET计算里最敏感的是辐射项,云量直接影响太阳辐射,所以云量输入错了,后面再怎么调风速都是白搭。

我一般会先跑一个晴天正午的单点测试,作为模型自检。比如7月15日中午12点,北纬40度,晴天无遮挡时太阳高度角大约68度,Cloud Cover设3成时到达地面的短波辐射会比晴天低不少,Tmrt也随之下降。如果跑出来的Tmrt比Ta高出25°C以上,说明辐射链路是通的;要是只差几度,先回去查云量和经纬度,别急着出图。这是最快能验证模型没写错参数的土办法。

2.2 输入参数边界:单位、范围和常见误用

RayManPro的输入面板看起来简单,实际每个字段都有边界约束。以下是我整理的参数表,单位、范围和常踩的坑都在里面。

参数单位常见范围常见误用
云量okta(0-8)0晴 ~ 8阴百分比或小数格式直接填
空气温度°C-40 ~ 60用开尔文或华氏度
相对湿度%(0-100)10 ~ 100把0.65当成65%
风速m/s0 ~ 30气象站的km/h没除以3.6
日期时间本地标准时逐时连续填UTC导致太阳位置错位
经纬度十进制度全球度分秒格式没转十进制度

先说云量。RayMan遵循气象上常用的okta分法,0到8,0是全晴,8是全阴。有的版本界面会给预设项(晴/多云/阴天),本质也是okta的取值范围。如果你手里的气象数据给的是百分比,除以12.5才是okta;给的是0-1的小数,乘以8就是okta。这个换算看起来简单,实际项目里最常翻车的就是这一步,原因很简单:气象站导出的云量字段绝大多数是百分比,直接贴进界面,模型会把云的衰减效果彻底算歪。

空气温度没有太多坑,注意单位就行。有些逐时数据集给的是开尔文,先减273.15再入库。相对湿度要注意气象数据里“0.65”这种小数,RayMan按0-100读取,必须乘100,否则蒸发散热算错,夏季PET会明显偏低。风速是第二个重灾区。很多环境气象站导出的是km/h,比如“7.2”,如果不除以3.6直接填,模型以为风速只有2 m/s,对流换热算少了,夏季白天PET偏高,冬季夜间PET偏低。我自己会在数据清洗阶段统一转好,并在结果里加合理性检查:同一时刻风速越大PET应该越低,要是风速填完PET反而升高,先怀疑单位。

时间列要格外小心。RayMan内部用真太阳时算太阳高度角,但你可以给它本地标准时,程序会按站点经度做修正。问题出在批量导入时,如果给的是UTC时间且没告诉模型,它就会按零度经线计算,下午的太阳高度角变成清晨的,Tmrt和PET完全失真。经纬度建议用十进制度,比如116.35而不是116°21′。老版本如果只认度分秒,脚本里手动做进制转换,别手敲,容易错。

回到业务层面,很多项目在没有RayMan之前直接拿空气温度定性“热不热”,这在辐射条件弱的阴天还行,遇到夏季晴天就失真:同一气温下,树荫里和广场中央的体感能差出一两个热等级,区别全在辐射项。PET把云量、风速、辐射全部折算进一个温度里,项目验收和方案比选才有一个能横向对比的物理量。

2.3 输出面板里到底看哪几列:Tmrt、PMV、PET、热等级

批量跑完,输出文件里通常一行一个时刻,列包含日期时间、空气温度、相对湿度、平均辐射温度Tmrt、风速、PET、PMV。不要只看最后一列,养成先看Tmrt的习惯。Tmrt是平均辐射温度,可以理解为人所处位置接收到的来自各方向辐射的等效温度。夏季晴天无遮挡时Tmrt能到60°C以上,比气温高三十多度;阴天或树荫下Tmrt贴近气温。Tmrt和气温的差,直接告诉你这个场地是辐射主导还是气温主导。

风速列也别跳过。人体热舒适对低风速非常敏感,1.5 m/s和3 m/s在评价里是两个量级,不要觉得这个数小就忽略它。把输出文件拉出来后,我的第一件事是画一条全时段Tmrt-Ta曲线,看昼夜差是否合理。夏季晴天白天差值应该在20°C以上,夜间回落到0°C附近。如果差值全天都很小,基本可以确定云量或遮挡表有问题。

PET根据热感觉等级划分区间,这套分级表在生物气象学应用里比较常用。

热觉等级PET范围(°C)
严寒< 4
寒冷4 ~ 8
凉8 ~ 13
稍凉13 ~ 18
舒适18 ~ 23
稍暖23 ~ 29
暖29 ~ 35
热35 ~ 41
酷热> 41

不同文献的区间有出入,比如有的把“暖”放在29-35,有的放在25-35。做正式报告时,以所在地区规范或甲方要求的分级为准,别拿一篇论文的区间往报告里硬套。PMV列也有,它是热感觉预测,-3到+3的数值,但PMV的舒适区间和PET不等价,不要混用。UTCI模型也支持,它和PET共用一套人体模型,只是参考环境设置不同,做城市设计比选时PET更常用,UTCI更多用在室外冷热应激的跨场景对比,输出面板里能看到,但别把两个指标的数值混在一起比较。

3. 跑通一次完整计算:数据准备、批量导入与参数设置

3.1 把气象数据整理成RayManPro能读的输入文件

如果只算一个时刻,直接手输没问题。但一旦要做整个夏季的逐时模拟,手动输入会改到崩溃,常见做法是把气象站导出的CSV转成RayManPro能识别的文本行。下面是清洗脚本,我拿它处理过几十份气象数据,列名按实际导出格式改就行。

import csv from datetime import datetime def convert_weather(csv_in, out_txt): # 典型气象站CSV列:time,temp_c,rh_pct,wind_kmh,cloud_pct with open(csv_in, 'r', encoding='utf-8') as f, \ open(out_txt, 'w', encoding='utf-8', newline='\r\n') as g: reader = csv.DictReader(f) for row in reader: dt = datetime.strptime(row['time'], '%Y-%m-%d %H:%M') ta = float(row['temp_c']) rh = float(row['rh_pct']) ws = float(row['wind_kmh']) / 3.6 # km/h -> m/s okta = float(row['cloud_pct']) / 12.5 # % -> okta g.write(f"{dt.strftime('%Y-%m-%d %H:%M')},{ta:.1f},{rh:.0f},{ws:.2f},{okta:.0f}\n") return out_txt

逻辑说明:先把气象站的逐时记录读进来,风速除以3.6从km/h转成m/s,云量除以12.5从百分比转成okta,然后按RayManPro的输入行格式逐行写出。重点在最后一项:out_txt指定了换行符\r\n。老版本RayManPro跑在Windows环境,读Unix的LF结尾文件会把整行连在一起,出现过解析错位,换成CRLF就稳了。编码上,如果导入后注释是乱码,把utf-8改成gbk试试,文件头有BOM的话一并处理掉。

时间格式要看你的RayManPro版本。新版本认YYYY-MM-DD HH:MM,老版本可能认DD.MM.YYYY HH:MM。不确定的时候,先拿Demo文件对比一下列格式再生成,不要一上来就批量导入几千行,返工成本太高。

3.2 两种计算入口:单点手输 vs 批量导入

单点计算适合测试。界面里填好日期时间、经纬度、空气温度、相对湿度、风速、云量,再把人体参数设置好,点计算直接出结果。我会用单点模式验证模型状态:先跑一个晴天正午、一个阴天夜间,如果白天PET比夜间高30°C以上,说明参数链路基本通;如果差距小,回去查时区和云量。

批量导入是实际项目的主力入口。把3.1生成的txt文件通过导入功能读进去,导入时注意时间属性设置:文件时间是本地标准时还是UTC、是否需要做时区修正,绝不能把下午两点当成凌晨两点算。导入后先看前24行的太阳高度角输出,如果凌晨出现正高度角,说明时间处理错了。正常情况太阳高度角在正午最高、夜间为负,这个检查十秒钟就能完成,却能省掉后面一整套废数据。

3.3 人体与服装参数怎么定

很多第一次用的人容易忽略人体参数,默认值直接点计算,算出来的PET可能和实际场景差出一个热等级。下面是我常用的参数模板。

场景身高(m)体重(kg)代谢率(W)服装热阻(clo)
广场静坐1.7065800.5(夏)/ 1.2(冬)
站姿交谈1.75701200.5 / 1.2
慢速步行1.75701800.6 / 1.4

代谢率代表人体产热水平,室外热舒适评价一般不会让人体处于跑步状态,选太高会让PET偏低。静坐选80W,站姿120W,慢走180W,够了。服装热阻夏季典型值0.5clo,春秋0.9clo,冬季1.2~1.8clo。评价不同季节要用不同clo,别用全年平均服装热阻,那会让冬季PET偏暖、夏季偏凉,结论直接反了。

位置遮挡是另一个经常被忽略的坑。RayMan默认站点周围无遮挡,人站在全天空开阔地。如果实测地点在建筑阴影里、树冠下面或高低错落的高楼之间,必须提供遮挡信息。粗算时常见做法是输入简化的遮挡角度:比如西侧有建筑,挡住高度角15°到45°的扇形区域,把这个范围填进遮挡表。这个粗糙模型比完全不设遮挡要准得多,晴天下午的PET能掉5°C以上。没有鱼眼照片的时候,先按场地平面图估几个主要遮挡方向,也比默认全天空开阔地强。

3.4 输出结果怎么看

批量跑完后,我按这个顺序自查。第一步,看Tmrt和空气温度的差值。夏季晴天无遮挡,Tmrt比Ta高20~40°C是正常的;如果差值只有几度,要么是云量设大了,要么是遮挡过度。第二步,看PET相对Ta的偏移。晴天白天PET通常比Ta高5~15°C,阴天接近Ta,夜间PET略低几度。如果白天PET比Ta还低,回去查风速单位。第三步,按分级表定热等级。做报告时把PET时变化曲线画出来,结合Tmrt看拐点,很多设计方案评价里的反常点,其实都是辐射项在作怪。

4. 避坑:RayManPro 跑百次模拟总结出来的五个翻车点

以下五条都是我在实际项目里踩过的,按出现频率排了序。这些坑大多数不是模型算法的问题,而是数据在进模型之前被改坏了,逐条复现现象、原因和解决路径,照着排查能省不少返工时间。

4.1 云量填成百分比,PET直接爆表

现象:夏季阴天云量80%的项目,算出来的PET高达40°C以上,比同一站晴天的结果还高。

原因:RayMan的云量输入按okta(0-8)读取,不识别百分比。直接填80,相当于让模型去处理一个远超全阴天量级的云量,辐射衰减计算出现反向修正,PET就爆了。

解决:入库前统一除以12.5,并把结果钳制到0-8范围。脚本里加一行断言,云量大于8直接报警,不要默默往下算。

4.2 风速单位当成km/h,冬季PET算成虫洞

现象:冬季傍晚实测风速7.2 km/h,界面里直接填7.2,算出来的PET低到-30°C,明显不合理。

原因:RayMan按m/s接收风速,7.2 km/h实际只有2 m/s,填成7.2 m/s相当于七级大风,对流换热和蒸发散热被放大好几倍,PET被压到异常低值。

解决:清洗脚本里统一除以3.6。输出后用夏季夜间校验:夜间PET和Ta的差应小于5°C,超过这个范围先查风速。

4.3 时间没转本地时,太阳位置整个错位

现象:批量导入的UTC时间文件,中午12点的Tmrt偏低,反而是下午2点出现接近0的太阳高度角。

原因:模型按输入的UTC时间配合站点经度计算太阳位置,没做时区转换时,当地正午被映射到了UTC坐标轴上,太阳轨迹整体平移。

解决:脚本里先把日期时间转成当地标准时,再写入输入文件。导入界面里明确选“文件时间为本地时间”,不要选UTC。验证方法很直接:看凌晨输出有没有太阳高度角。

4.4 树荫下的站点PET异常高

现象:实测地点在树冠下,夏季晴天PET算出来45°C,体感明显没这么热。

原因:没输遮挡表,模型默认全天空开阔,短波辐射全额照射到人体表面,辐射项被严重高估。

解决:至少输入简化遮挡角度表,把树冠或建筑大概挡住的方向和高度角填进去。同时检查反照率:草地设0.25,硬质地面设0.30,水面设0.10,别全用默认值。

4.5 输出CSV列错位,PET串到风速列

现象:导出的结果文件用Excel打开,PET列的数字出现在风速列,整排错位。

原因:老程序输出分隔符受系统区域设置影响,非英文环境下可能用分号或制表符,用户按逗号拆分,自然错位。

解决:用Python的read_csv指定sep='\t|;|,',统一转成标准CSV后再交付。不要直接拿原始输出文件进Excel做图。

排查顺序建议:结果异常时按“时间属性 → 云量 → 风速 → 遮挡 → 区域格式”的顺序过一遍。这个顺序覆盖了我会踩的绝大多数坑,跳过任何一步都可能白查半天。

5. 把PET用起来:输出解析、插值成图与缺测处理

5.1 解析RayManPro输出文件

批量模拟得到的是文本输出,直接拖进Excel容易踩第4.5条的坑,先写脚本解析成干净的DataFrame。

import pandas as pd def read_rayman_out(txt_path): # RayMan输出常见列:Time,Ta,RH,Tmrt,Uwind,PET,PMV df = pd.read_csv(txt_path, sep='\t|;|,', engine='python', skiprows=1) df['PET'] = pd.to_numeric(df['PET'], errors='coerce') # 缺测标记常见为 -999 df.loc[df['PET'] < -900, 'PET'] = float('nan') return df

逻辑说明:老版本输出有时候是制表符,有时候是分号,取决于运行机器的区域设置,所以用正则分隔符把三种分隔符一并处理。PET缺测值常见是-999,先置成NaN,后面画图和统计才不会带出离谱的尖峰。skiprows=1是跳掉版本信息行,如果你的输出文件没有这行,去掉即可。

5.2 多点位PET插值出热力图

单点位PET只能评价一个点,场地评价需要多点位空间分布。常见做法是在模拟项目X的场地里布四个测点,分别跑出PET,再做插值。

import numpy as np from scipy.interpolate import RBFInterpolator import matplotlib.pyplot as plt # 四个测点的坐标和PET值,模拟项目X的场地范围 pts = np.array([[0,0],[0,50],[50,0],[50,50]], dtype=float) vals = np.array([32.5, 28.9, 31.2, 26.4]) # 由RayMan批量跑出 grid_x, grid_y = np.meshgrid(np.linspace(0,50,200), np.linspace(0,50,200)) interp = RBFInterpolator(pts, vals, kernel='linear') grid_pet = interp(np.column_stack([grid_x.ravel(), grid_y.ravel()])).reshape(grid_x.shape) plt.imshow(grid_pet, extent=[0,50,0,50], origin='lower', cmap='RdYlBu_r') plt.colorbar(label='PET (°C)') plt.scatter(pts[:,0], pts[:,1], c='k', marker='o') plt.savefig('pet_map.png', dpi=300)

说明:测点少于四个的场地,RBF插值就够用,核选linear不容易外推出离谱值;测点多的话换IDW或克里金,避免插值圈在边界外推失真。网格分辨率按场地尺寸设:50米见方的场地,200×200网格已经够平滑,再密是视觉上的浪费。画图前先检查测点PET值域,如果出现插值结果低于所有测点极值的区域,说明边界外推太猛,把网格范围收进测点凸包内。

5.3 输入数据不是逐小时时:重采样和缺测处理

气象站数据经常不是逐小时的。常见做法是先把时间轴重采样成1小时间隔,空气温度和相对湿度用线性插值,风速用最近值填充,云量不要平滑。云量变化对太阳辐射的影响是跳跃性的,平滑掉会直接削弱午后辐射峰值。

# 气温湿度线性插值,风速nearest填充,云量ffill但仅限3小时 df_ta = df.resample('1h').interpolate(method='time') df_ws = df.resample('1h').nearest() df_cloud = df.resample('1h').ffill(limit=3)

参数说明:interpolate(method='time')按时间间隔线性插值,适合气温和湿度这种连续变量。云量的ffill带limit=3,意思是云量值最多向前填充3小时,超过就置空,避免把一段长空窗伪装成稳定趋势。缺测超过6小时的数据段,我一般直接置NaN并在报告里标注,不硬插。

5.4 结果怎么验证

没有实测PET时,验证分两步走。第一步是中间量验证:用黑球温度实测折算出Tmrt,和RayMan输出的Tmrt对比,偏差在±5°C以内说明辐射场模拟可靠;偏差超过8°C,先查云量和遮挡表。第二步是PET区间验证,参考下面这张自查表。

检查项合理参考超限先查
Tmrt - Ta晴日白天 20~40,夜间 0±5云量、遮挡
白天 PET vs Ta高 5~15风速单位、反照率
夜间 PET vs Ta接近或略低时间、时区

UTCI也可以用来做交叉验证,但PET和UTCI的区间不能直接换算,输出里对比时分开画两条曲线,别混在一起下结论。做完这步,你手里的PET才算是一个能拿去写报告的数据,而不是模型吐出来的数字。

6. 批量情景比选:用脚本把不同设计方案跑出对比表

实际项目里RayManPro最常用的不是出一张图,而是方案比选。比如景观设计要比较“无遮挡广场、加树阵、加廊架”三种方案在7月某天的PET差异,人肉改遮挡表会改到崩溃。常见做法是写一个Python脚本,把RayManPro当作批处理工具循环调用。

from pathlib import Path import subprocess, shutil base_dir = Path('/tmp/rayman_runs') scenarios = [ {'name': 'no_shade', 'shade_deg': None, 'albedo': 0.30}, {'name': 'tree_row', 'shade_deg': 'tree.txt', 'albedo': 0.25}, {'name': 'pergola', 'shade_deg': 'pergola.txt', 'albedo': 0.30}, ] for s in scenarios: run_dir = base_dir / s['name'] run_dir.mkdir(parents=True, exist_ok=True) shutil.copy('weather_20230715.txt', run_dir / 'weather.txt') write_config(run_dir, s) # 把遮挡文件和反照率写进配置 ret = subprocess.run( ['RayManProConsole.exe', str(run_dir / 'weather.txt')], capture_output=True, timeout=600) if ret.returncode != 0: print(s['name'], 'fail, see stderr') continue extract_results(run_dir) # 解析PET列并汇总

参数说明:每个方案放独立目录,最核心的坑是RayManPro输出文件名固定,多个实例同时跑会在同一个目录里互相覆盖输出文件,独立目录从根上解决了这个问题。timeout=600是给单日逐时模拟留的余量。并发度控制在2到3个进程,开太多内存会吃紧。注意遮挡表格式要和版本一致,模拟项目X里用的是横纵角格式,直接照Demo改就行。

跑完后把PET最大值、出现时刻、下午均值三列汇总成对比表,方案优劣一眼就能看出来。从那以后我每次接手新的气候评价项目,都强制把气象数据清洗、单位换算、RayMan批量模拟、Tmrt自查、分级出图这一套流程完整走一遍,哪怕只算一天的数据也不跳过。这个流程帮我把返工率降了一大截,项目评审会上也很少再被质疑“这个数怎么来的”。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询