8000 Rewrite the growers page as a task path with a worked tomato example (#80) by rafatahmed · Pull Request #88 · rafatahmed/Flahax · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- Rewrite the growers page as a task path (#80): enter the water analysis (with unit conversions, measured zeros and detection limits), choose the formula, run `flahax batch`, read the batch sheet; then a worked tomato example on the station 104 well blended with RO water (8% passes the 3 mmol/L Na and Cl limits, 9% is blocked), what to measure after mixing and when to call an agronomist. A test reruns the example and checks the page's numbers. `flahax batch --water-share PERCENT` blends the analysed water with ion-free water: nutrients and limits scale the laboratory values and the chemistry dilutes the measured-pH record (#84). Formulation and pH stages that need review now say why (incidental nutrients without a declared maximum; the chosen reagent's review findings and missed targets) instead of an empty reason.
- Fix `recommend()` raising 'NNLS did not reach optimality' when the source water alone exceeds one declared maximum while another is binding (#86), for example 9% of the station 104 well with Na and Cl maxima of 3 mmol/L. A ceiling the water already reaches cannot be met, so its Lagrange search grew the shift without bound (#68) until NNLS failed. Products carrying that ion are now left out of the fit directly, the infinite-multiplier limit the search was approaching, and the excess is reported in `limitViolations` as before. Over 312 formula, water-share and ceiling cases the recipes are identical wherever the old search succeeded, and the failing cases now equal the fit without chloride products.
- Concentration limits and nutrient targets now always use the laboratory water analysis; the charge-balanced water is used for chemistry only (#84). `balance_water_analysis` closes an analysis' charge on chloride or sodium, a modelling step, but its totals were passed on as the water: the nitric delivery stage rebuilt its nutrient rows and limits from them, `flahax batch` (#79) formulated on them, and the tomato example chose its blend on them. On Shomar et al. (2024) station 104 the model has 1158.5 mg/L chloride against 1280.4 measured, so the example reported 9% well water as within the 3 mmol/L chloride limit; on the laboratory value 9% is 115.2 mg/L and fails, and 8% (102.4 mg/L) is the largest passing share (boundary about 8.3%). Balancing on sodium raises sodium from 680 to 759 mg/L, so the error could also reject a passing water. Now `BalancedWaterAnalysis` keeps `analytical_totals` (the analysis as entered, defensively copied) beside the model, with its provenance, and `diluted(fraction)` blends it with ion-free water, scaling both and recomputing the blend's chemistry. The workflow accepts such a record as `equilibrium['water_balance']`, rejects contradictory water inputs, passes `analytical_water_totals` to `plan_equilibrium_delivery` (rows and limits on the analysis, dose on the chemistry), and reports laboratory and modelled water in `water_basis`. When the balancing alone would change a limit decision the plan is `requires_review` with the reason; a laboratory-basis exceedance always blocks, and a review never downgrades a block. The coupled pH planner's no-reagent-needed candidate now gets the same limit and saturation checks as dosed candidates (it skipped both), and the workflow rechecks the selected plan's limits. Balanci 6AFA ng itself is now explicit: an analysis that already closes at its measured pH (within 0.0001% of its total charge) is used unchanged and needs no balance ion, so chloride-free waters no longer fail on the default chloride; `CO3-2` = 0 marks measured carbon-free water (omitted carbon is still `missing_carbon`); measured zeros and `below_detection` components are held fixed; the closure is `reconciled` only within a stated `balance_ion_uncertainty_percent` (else `reconciliation_out_of_bounds`), and without one it is `assumed` and the chemistry, and every plan built on it, asks for review. No other ion is tried automatically (`fixed_balance_ion`). `flahax batch` takes nutrients straight from the analysis file, accepts measured zeros, detection limits, a balance ion and its uncertainty, and gains `--limit SYMBOL=MG_PER_L`; undeclared limits are never assumed. The report shows laboratory, modelled and adjusted water, each limit with its decision basis, and the batch sheet the limits on the laboratory basis. The tomato example now blends 8% well water and every dependent number is recomputed; the publication example keeps its 1:3 blend, and only its printed blend chloride changes (290 -> 320 mg/L, the laboratory value). The grower-outputs page now gives the 5% imbalance screen (it said 10%).
- Ship the grower outputs in the package (#79). They were example code only (#73), so an installed FlahaX gave growers JSON. New `flahax batch` command: one formula (packaged, or your targets) and one water (`ro` or a measured analysis, closed at its pH) to `report.html`, `batch-sheet.html` and `summary.json`, with the coupled pH plan (your acids from certificate values, plus the packaged bases). In Python, `summarize_batch`, `render_report` and `render_batch_sheet` do the same from any `plan_fertilizer_workflow` result; when a reagent is selected the sheet weighs the refitted recipe that counts its nutrients. `group_tanks` is the sourced default concentrate grouping: the Yara page 65 compatibility table (read with page 63) as three composition rules (calcium with phosphate, calcium with sulfate, magnesium with phosphate), which reproduce its twelve incompatible pairs exactly; micronutrients and chelates go to tank A with calcium and stay out of phosphate concentrates, and tank A is never acidified (owner rule). The tomato examples use it, so micronutrients no longer show as 'Not in table'; their acid text now reflects #78 (nitric needs review, phosphoric misses P). `default_compatibility_rules` gives `plan_stocks` the same rules as records. Stock solubility is still not checked: the outputs say so.
- Positive saturation indices of phases that do not form at feed conditions no longer reject pH and delivery plans (#78). FlahaX and live PHREEQC 3.8.6 agree on every sign at the coupled target states, so the indices are right; the question was which phases form. Hydroxylapatite (precursor pathway, magnesium-inhibited), goethite (forms slowly from ferrihydrite), anhydrous MnHPO4 (unmeasured constant, log K -25.4 from 1976 program data; not reported to form at 25 C or in dilute feeds) and vivianite (Fe(II) phosphate of reducing environments; the model holds Fe(II) fixed) now make a plan `requires_review`, each with its reason and sources; feeds containing iron(II) carry an advisory that the iron oxidizes and precipitates as Fe(III) phosphate. Brushite, monetite, gypsum, struvite, calcite, ferrihydrite and every other phase, and any allocated solid, still reject. One policy (`saturation_policy.py`) now serves the coupled pH plan, acid selection, equilibrium delivery and plan validation. In the 26-formula RO-water audit at pH 5.8, 21 formulas now get a usable pH plan (12 also meet every target), against none before; the 5 still rejected have monetite or brushite supersaturated. Owner decision and cited research summary on #78.
Expand Down
Loading
Loading
0