🎉 init(init):初始化仓库

This commit is contained in:
张鑫
2025-12-23 08:38:08 +08:00
parent 36226cc9fe
commit 066fe58f89
34 changed files with 3402 additions and 2 deletions

View File

@@ -0,0 +1,365 @@
from datetime import datetime, timedelta
from pyeto import fao,convert
from pyeto.fao import svp_from_t, avp_from_rhmean, delta_svp, psy_const,atm_pressure
import pandas as pd
#1、计算日参考蒸散量
def calculateET0(tmean, tmax, tmin, rh_mean, wind_speed, solar_rad, elevation, lat, doy):
# 计算饱和水汽压和实际水汽压
svp_max = svp_from_t(tmax)
svp_min = svp_from_t(tmin)
svp_mean =(svp_max+svp_min)/2
avp = avp_from_rhmean(svp_max, svp_min, rh_mean)
# 计算净辐射(简化版)
# 将纬度从度转换为弧度
lat_rad = convert.deg2rad(lat)
sol_dec = fao.sol_dec(doy)
sha = fao.sunset_hour_angle(lat_rad, sol_dec)
ird = fao.inv_rel_dist_earth_sun(doy)
et_rad = fao.et_rad(lat_rad, sol_dec, sha, ird)
cs_rad = fao.cs_rad(elevation, et_rad)
nisr = fao.net_in_sol_rad(solar_rad)
nolr = fao.net_out_lw_rad(tmin, tmax, solar_rad, cs_rad, avp)
rn = fao.net_rad(nisr, nolr)
deltasvp= delta_svp(tmean)
psy = psy_const(atm_pressure(elevation))
# 计算ET₀
et0 = fao.fao56_penman_monteith(
net_rad=rn,
t=tmean,
ws=wind_speed,
svp=svp_mean,
avp=avp,
delta_svp=deltasvp,
psy=psy
)
return et0
def cal_et0_List(planting_date,monitor_date,date_params):
et0_list = []
current_date = planting_date
while current_date < monitor_date:
result_params=date_params[current_date.strftime("%Y-%m-%d")]
et0=calculateET0(result_params['tmean'], result_params['tmax'], result_params['tmin'], result_params['rh_mean'], result_params['wind_speed'],
result_params['solar_rad'], result_params['elevation'],result_params['lat'], result_params['doy'])
et0_list.append(et0)
current_date += timedelta(days=1) # 增加一天
return et0_list
#计算实际每天作物蒸散量
# 1. 定义甘草生育阶段与作物系数(参考苜蓿)
# growth_stages = {
# "initial": {"duration_days": 20, "kc": 0.40}, # 生长初期
# "development": {"duration_days": 40, "kc": 0.90}, #生长快速期
# "mid": {"duration_days": 20, "kc": 1.1}, # 生长缓慢期
# "growth_slowly": {"duration_days": 30, "kc": 0.6}, # 生长缓慢期
# "dormant_period": {"duration_days": 150, "kc": 0.40}, # 营养储备期
# "fanqing_year2":{"duration_days": 30, "kc": 0.35},#返青期
# "development_year2":{"duration_days": 90, "kc": 0.9}, #第二年快速生长期
# "maturity _year2": {"duration_days": 40, "kc": 0.6}, # 第二年成熟期
# }
growth_stages_roots1 = {
'initial': {
'root_length': {5: 0.8, 10: 0.2}, # 主根长80%概率在0-15cm平均约8cm
'duration_days': 23, # 6月播种后1-2周
'kc': 0.40, # 作物系数
'time_range': '2025-06-17至2025-07-10',
'hight':0.03,#m
'k_rain':0.25
},
'development': {
'root_length': {20: 0.6, 45: 0.4}, # 主根长60%概率在20cm40%概率在45cm平均约30cm
'duration_days': 40, # 发芽后-8月20日左右约2个月
'kc': 0.9, # 作物系数
'time_range': '2025-07-10至2025-08-20',
'hight':0.15,
'k_rain':0.25
},
'mid': {
'root_length': {30: 0.5, 80: 0.5}, # 主根长50%概率在30cm50%概率在80cm平均约55cm
'duration_days': 30, # 8月20日-9月下旬
'kc': 1.1, # 作物系数
'time_range': '2025-08-21至2025-09-20',
'hight':0.45,
'soil_evaporation_depth': 0.65,
'k_rain':0.4
},
'growth_slowly': {
'root_length':{40: 0.4,60:0.4, 80: 0.2}, # 根据数据估算平均主根长
'duration_days': 30, # 9月下旬-10月下旬
'kc': 0.6,
'time_range': '2025-09-21至2025-10-20',
'hight':0.6
},
'dormant_period': {
'root_length': {40: 0.3,60:0.4, 80: 0.2}, # 冬季休眠,主根基本停止生长
'duration_days': 160, # 11月-次年3月
'kc': 0.4,
'time_range': '2025-10-21至2026-03-30',
'hight':0.8,
'k_rain':0.5
},
'fanqing_year2': {
'root_length': {40: 0.2,60:0.6, 80: 0.2}, # 返青期主根长变化不大
'duration_days': 30, # 3月下旬-4月下旬
'kc': 0.35,
'time_range': '2026-04-01至2026-04-30',
'hight':0.5,
'k_rain':0.5
},
'development_year2': {
'root_length': {40: 0.1,60:0.7, 80: 0.2}, # 根据数据估算平均主根长
'duration_days': 90, # 4月下旬-7月下旬
'kc': 0.9,
'time_range': '2026-05-01至2026-07-30',
'hight':0.45,
'k_rain':0.65
},
'maturity_year2': {
'root_length':{40: 0.1,60:0.6, 80: 0.3}, # 根据数据估算平均主根长
'duration_days': 40, # 7月下旬-8月下旬
'kc': 0.6,
'time_range': '2026-08-01至2026-09-10',
'hight':0.65,
'k_rain':0.5
}
}
# growth_stages_roots = {
# 'initial': {
# 'root_length': {5: 0.8, 10: 0.2}, # 主根长80%概率在0-15cm平均约8cm
# 'duration_days': 20, # 6月播种后1-2周
# 'kc': 0.40, # 作物系数
# 'time_range': '2025-07-08至2025-07-28',
# 'hight':0.03,#m
# 'k_rain':0.25
# },
# 'development': {
# 'root_length': {20: 0.6, 45: 0.4}, # 主根长60%概率在20cm40%概率在45cm平均约30cm
# 'duration_days': 42, # 发芽后-8月20日左右约2个月
# 'kc': 0.9, # 作物系数
# 'time_range': '2025-07-29至2025-09-10',
# 'hight':0.15,
# 'k_rain':0.25
# },
# 'mid': {
# 'root_length': {30: 0.5, 80: 0.5}, # 主根长50%概率在30cm50%概率在80cm平均约55cm
# 'duration_days': 30, # 8月20日-9月下旬
# 'kc': 1.1, # 作物系数
# 'time_range': '2025-09-11至2025-10-10',
# 'hight':0.45,
# 'soil_evaporation_depth': 0.65,
# 'k_rain':0.4
# },
# 'growth_slowly': {
# 'root_length':{40: 0.4,60:0.4, 80: 0.2}, # 根据数据估算平均主根长
# 'duration_days': 31, # 9月下旬-10月下旬
# 'kc': 0.6,
# 'time_range': '2025-10-11至2025-11-10',
# 'hight':0.6
# },
# 'dormant_period': {
# 'root_length': {40: 0.3,60:0.4, 80: 0.2}, # 冬季休眠,主根基本停止生长
# 'duration_days': 140, # 11月-次年3月
# 'kc': 0.4,
# 'time_range': '2025-11-11至2026-03-31',
# 'hight':0.8,
# 'k_rain':0.5
# },
# 'fanqing_year2': {
# 'root_length': {40: 0.2,60:0.6, 80: 0.2}, # 返青期主根长变化不大
# 'duration_days': 30, # 3月下旬-4月下旬
# 'kc': 0.35,
# 'time_range': '2026-04-01至2026-04-30',
# 'hight':0.5,
# 'k_rain':0.5
# },
# 'development_year2': {
# 'root_length': {40: 0.1,60:0.7, 80: 0.2}, # 根据数据估算平均主根长
# 'duration_days': 90, # 4月下旬-7月下旬
# 'kc': 0.9,
# 'time_range': '2026-05-01至2026-07-30',
# 'hight':0.45,
# 'k_rain':0.65
# },
# 'maturity_year2': {
# 'root_length':{40: 0.1,60:0.6, 80: 0.3}, # 根据数据估算平均主根长
# 'duration_days': 40, # 7月下旬-8月下旬
# 'kc': 0.6,
# 'time_range': '2026-08-01至2026-09-10',
# 'hight':0.65,
# 'k_rain':0.5
# }
# }
# ---------------------------
# 2. 计算每日Kc值根据生育阶段动态分配
# ---------------------------
def get_daily_kc(growth_stages, total_days=423):
daily_kc = []
for stage in growth_stages.values():
daily_kc.extend([stage["kc"]] * stage["duration_days"])
# 如果总天数超出定义用末期Kc填充剩余天数
if len(daily_kc) < total_days:
daily_kc.extend([growth_stages["maturity_year2"]["kc"]] * (total_days - len(daily_kc)))
return daily_kc[:total_days] # 截断至总天数
# ---------------------------
# 3. 计算每日实际蒸散量ETc(得到历史列表)
# ---------------------------
def calculate_etc_List(et0_daily, planting_date,monitor_date, kc_daily):
"""
计算每日ETc实际蒸散量
:param eto_daily: 每日参考蒸散量列表单位cm/d
:param planting_date: 播种日期,格式"YYYY-MM-DD"
:param kc_daily: 每日Kc值列表
:return: 日期列表、ETc列表
"""
start_date = planting_date
delta=monitor_date-start_date
days = delta.days
dates = [start_date + timedelta(days=i) for i in range(days)]
date_strings = [date.strftime("%Y-%m-%d") for date in dates]
kc_daily = kc_daily[:days]
etc = [eto * kc for eto, kc in zip(et0_daily, kc_daily)]
return etc,date_strings,kc_daily
#基于作物蒸散和土壤蒸发计算实际蒸散量
def calculate_etc_List_new(et0_daily, planting_date,monitor_date, kc_daily,ke_daily):
"""
计算每日ETc实际蒸散量
:param eto_daily: 每日参考蒸散量列表单位cm/d
:param planting_date: 播种日期,格式"YYYY-MM-DD"
:param kc_daily: 每日Kc值列表
:return: 日期列表、ETc列表
"""
start_date = planting_date
delta=monitor_date-start_date
days = delta.days
dates = [start_date + timedelta(days=i) for i in range(days)]
date_strings = [date.strftime("%Y-%m-%d") for date in dates]
kc_daily = kc_daily[:days]
etc = [eto * (kc+ke) for eto, kc,ke in zip(et0_daily, kc_daily,ke_daily)]
return etc,date_strings,kc_daily
def calculate_etc_dayily(et0_daily, planting_date,monitor_date, kc_daily):
"""
计算每日ETc实际蒸散量
:param eto_daily: 每日参考蒸散量列表单位cm/d
:param planting_date: 播种日期,格式"YYYY-MM-DD"
:param kc_daily: 每日Kc值列表
:return: 日期列表、ETc列表
"""
start_date = planting_date
delta=monitor_date-start_date
days = delta.days
# dates = [start_date + timedelta(days=i) for i in range(len(kc_daily))]
kc_daily = kc_daily[days]
etc = et0_daily*kc_daily
return etc
def export_etc_et0_date(et0_list,etc_list,dates,kc_list,ke_daily,soil_data,rain_daily,irrigate_daily,dk_name):
df = pd.DataFrame({
"Date": dates,
"ET0": [float(f"{x:.3f}") for x in et0_list],
"KC": kc_list,
"KE":ke_daily,
"ETc": [float(f"{x:.3f}") for x in etc_list],
"rain_effective":rain_daily,
"I_effective":irrigate_daily,
"VWC_fc":0.2884,
"VWC_wp":0.1086,
"dkbm":dk_name
})
df['VWC_SUR'] = 0.0
df['VWC_MID'] = 0.0
df['VWC_BOT'] = 0.0
for i in range(len(df)):
date=df.at[i, 'Date']
df.at[i, 'VWC_SUR']=round(float(soil_data["SOIL_MOISTURE_SURFACE"][date]),3)
df.at[i, 'VWC_MID'] = round(float(soil_data["SOIL_MOISTURE_MIDDLE"][date]),3)
df.at[i, 'VWC_BOT'] = round(float(soil_data["SOIL_MOISTURE_BOTTOM"][date]),3)
return df
def estimate_mad_from_et(max_et):
# 根据最大日蒸散量查表确定MAD值
if max_et < 2:
mad = 0.68
elif 2 <= max_et < 3:
mad = 0.58
elif 3 <= max_et < 4:
mad = 0.48
elif 4 <= max_et < 5:
mad = 0.4
elif 5 <= max_et < 6:
mad = 0.35
elif 6 <= max_et < 7:
mad = 0.33
elif 7 <= max_et < 8:
mad = 0.28
elif 8 <= max_et < 9:
mad = 0.25
else: # max_et >= 8
mad = 0.23
return mad
def calculate_weighted_soil_parameters(root_distribution, soil_layers):
# 初始化累计变量
sum_fc = 0.0
sum_wp = 0.0
# 处理每个根系分布层
for root_depth, root_ratio in root_distribution['root_length'].items():
# 找到包含该深度的土壤层
for layer in soil_layers:
min_depth, max_depth = layer['depth_range']
if min_depth <= root_depth < max_depth:
# 计算该层贡献 (简单比例分配)
layer_thickness = max_depth - min_depth
depth_in_layer = min(root_depth, max_depth) - min_depth
contribution_ratio = depth_in_layer / layer_thickness * root_ratio
sum_fc += layer['theta_33'] * contribution_ratio
sum_wp += layer['theta_1500'] * contribution_ratio
break
return sum_fc, sum_wp
def cal_stagebyDate(monitor_date,zwlx_growth_stages):
for stage, details in zwlx_growth_stages.items():
time_range_str = details['time_range']
if type(monitor_date) is str:
monitor_date= datetime.strptime(monitor_date, '%Y-%m-%d')
if '-' in time_range_str:
start_str, end_str = time_range_str.split('')
start_date = datetime.strptime(start_str, '%Y-%m-%d')
end_date = datetime.strptime(end_str, '%Y-%m-%d')
if start_date <= monitor_date <= end_date:
return stage,details['root_length'],details['hight'],details['k_rain']
raise ValueError(f"监测日期 {monitor_date.strftime('%Y-%m-%d')} 不在任何生育阶段范围内")
#根据日期计算主根长度
def calculate_average_root_length(root_length_dist):
return sum(length * prob for length, prob in root_length_dist.items())
def cal_soil_fc_wp():
# 土壤分层数据 (33kPa和1500kPa对应的含水率)
soil_data = [
{'depth_range': (0, 5), 'theta_33': 0.296, 'theta_1500': 0.103},
{'depth_range': (5, 15), 'theta_33': 0.284, 'theta_1500': 0.104},
{'depth_range': (15, 30), 'theta_33': 0.286, 'theta_1500': 0.105},
{'depth_range': (30, 60), 'theta_33': 0.290, 'theta_1500': 0.114},
{'depth_range': (60, 100), 'theta_33': 0.286, 'theta_1500': 0.117},
{'depth_range': (100, 200), 'theta_33': 0.284, 'theta_1500': 0.114}
]
# theta_fc, theta_wp = calculate_weighted_soil_parameters(
# growth_stages_roots[stage],
# soil_data
# )
theta_fc=0.2884
theta_wp=0.1086
return theta_fc,theta_wp
if __name__ == "__main__":
# #cal_et0_List(datetime(2026, 6, 18),datetime(2026, 6, 22))
et0_daily=[23,45,67,89]
# etc,dates,kc_daily=calculate_etc_List(et0_daily, datetime(2026, 6, 18),datetime(2026, 6, 22), get_daily_kc(growth_stages_roots))
# calculate_etc_dayily(45, datetime(2026, 6, 18), datetime(2026, 6, 22), get_daily_kc(growth_stages))
# df=export_etc_et0_date(et0_daily,etc,dates,kc_daily)
# print(df)
# cal_soil_fc_wp('initial')
# stage,details = cal_stagebyDate(datetime(2025, 7, 18))
# print(details)
# rd=calculate_average_root_length(details)
# print(rd)