Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Backlog Item]: Build a prototype of differentiable wofost72_pp

Open
#3 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Feature
Clarity
Needs clarification
Activity status
Stale
Tech stack
python, pytorch

Research direction

Start by locating the current WOFOST72_PP implementation and reviewing the related work in issues #7 and #13. Define the prototype’s differentiability and optimization acceptance criteria before attempting the end-to-end design; this issue names no target files or tests.

Written by the indexing model from the issue text.

Description

Backlog item Epic 1 scientific

The goal is to build a working differentiable wofost72_pp, supporting gradient-based optimization. To make the entire model end-to-end differentiable, the mathematics would be:

$$
\frac{\partial \text{loss}}{\partial \text{(ML model weights)}} =
\frac{\partial \text{loss}}{\partial \text{(differentiable wofost72-pp output)}} \cdot
\frac{\partial \text{(differentiable wofost72-pp output)}}{\partial \text{(wofost72-pp parameters)}} \cdot
\frac{\partial \text{(wofost72-pp parameters)}}{\partial \text{(ML model weights)}}
$$

This approach where an ML model predicts physical parameters, which are then used in a physics-based model, and combines both in a hybrid architecture, is a state-of-the-art approach and is known under various names. See recent publication "Scientific Machine Learning". See similar works at #7 and #13.

The prototype might be:

import torch.nn as nn

# Step 1: ML model that outputs physical parameters e.g. LSTM
class MLModel(nn.Module):
    def __init__(self, input_size, hidden_size, num_physical_params):
        super().__init__()
        self.lstm = nn.LSTM(input_size=input_size, hidden_size=hidden_size, batch_first=True)
        self.linear = nn.Linear(hidden_size, num_physical_params)

    def forward(self, x):
        lstm_out, _ = self.lstm(x)              
        physical_params = self.linear(lstm_out[:, -1, :]) 
        return physical_params

# Step 2: Physical model using Euler integration
class PhysicalModel(nn.Module):
    def __init__(self, dt):
        super().__init__()

    def forward(self, params):
        wofost = Wofost72_PP(params, ...) # this is differentiable version
        wofost.run_till_terminate()
        output = wofost.get_output()
        return output

# Step 3: Hybrid model integrating ML and physical model
class HybridModel(nn.Module):
    def __init__(self, input_size, hidden_size, num_physical_params):
        super().__init__()
        self.ml_model = MLModel(input_size, hidden_size, num_physical_params)
        self.physical_model = PhysicalModel()

    def forward(self, x):
        physical_params = self.ml_model(x)
        output = self.physical_model(physical_params)
        return output, physical_params

Regarding this structure, add your comments/suggestions below.

Dominant language
Python
Stars
25
Forks
7
Avg merge
2d 23h
Merged PRs (30d)
1

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from WUR-AI/diffWOFOST

All issues in WUR-AI/diffWOFOST

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.