FluxCd_output.py 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. from sqlalchemy import Column, Integer, Float, ForeignKeyConstraint
  2. from app.database import Base
  3. from app.models import FluxCdInputData, SoilData
  4. class FluxCdOutputData(Base):
  5. """
  6. 通量镉预测模型输出数据模型
  7. @param {int} id - 主键ID(自增)
  8. @param {int} farmland_id - 区域农业用地矢量点编号(关联Farmland_data表)
  9. @param {int} sample_id - 采样点ID(关联Farmland_data表)
  10. @param {float} in_cd - Cd输入总通量(g/ha/a)
  11. @param {float} out_cd - Cd输出总通量(g/ha/a)
  12. @param {float} net_cd - Cd净通量(g/ha/a)
  13. @param {float} end_cd - 当年Cd浓度(mg/kg)
  14. """
  15. __tablename__ = 'FluxCd_output_data'
  16. id = Column('ID', Integer, primary_key=True, autoincrement=True)
  17. farmland_id = Column('Farmland_ID', Integer)
  18. sample_id = Column('Sample_ID', Integer)
  19. in_cd = Column('In_Cd', Float, nullable=True)
  20. out_cd = Column('Out_Cd', Float, nullable=True)
  21. net_cd = Column('Net_Cd', Float, nullable=True)
  22. end_cd = Column('End_Cd', Float, nullable=True)
  23. # 定义复合外键,关联到Farmland_data表
  24. __table_args__ = (
  25. ForeignKeyConstraint(
  26. ['Farmland_ID', 'Sample_ID'],
  27. ['Farmland_data.Farmland_ID', 'Farmland_data.Sample_ID']
  28. ),
  29. {'comment': '通量镉预测模型输出数据'}
  30. )
  31. def calculate_fluxes(self, input_data: FluxCdInputData):
  32. """根据输入数据计算通量"""
  33. self.in_cd = input_data.input_flux()
  34. self.out_cd = input_data.output_flux() # 使用输出通量方法
  35. self.net_cd = self.in_cd - self.out_cd
  36. # 在 app/models/effcd_output.py 的 FluxCdOutputData 类中添加以下方法
  37. def calculate_end_cd(self, db_session):
  38. """
  39. 计算当年Cd浓度(mg/kg)
  40. 公式: (Initial_Cd + Net_Cd) / (2000 * bd020_90)
  41. @param db_session: 数据库会话
  42. @return: 计算后的Cd浓度值
  43. """
  44. try:
  45. # 1. 获取初始Cd浓度(Initial_Cd) - 从FluxCdInputData表
  46. input_data = db_session.query(FluxCdInputData).filter(
  47. FluxCdInputData.farmland_id == self.farmland_id,
  48. FluxCdInputData.sample_id == self.sample_id
  49. ).first()
  50. if not input_data:
  51. raise ValueError("未找到对应的输入通量数据")
  52. initial_cd = input_data.initial_cd # 单位: g/ha
  53. # 2. 获取土壤容重(bd020_90) - 从SoilData表
  54. soil_data = db_session.query(SoilData).filter(
  55. SoilData.farmland_id == self.farmland_id,
  56. SoilData.sample_id == self.sample_id
  57. ).first()
  58. if not soil_data:
  59. raise ValueError("未找到对应的土壤数据")
  60. bd020_90 = soil_data.bd020_90 # 单位: g/cm³
  61. # 3. 计算当年Cd浓度
  62. # 注意单位转换:
  63. # - Initial_Cd和Net_Cd单位是g/ha
  64. # - 1 ha = 10,000 m²
  65. # - 假设计算深度为20cm(0.2m),所以体积为2000 m³/ha
  66. # - bd020_90单位是g/cm³ = 1000 kg/m³
  67. # 公式推导:
  68. # (g/ha) / (2000 m³/ha * 1000 kg/m³) = (g/ha) / (2,000,000 kg/ha) = mg/kg
  69. end_cd = (initial_cd + self.net_cd) / (2000 * bd020_90)
  70. # 更新并返回结果
  71. self.end_cd = end_cd
  72. return end_cd
  73. except Exception as e:
  74. raise ValueError(f"计算当年Cd浓度失败: {str(e)}")