Skip to content

Releases

FlahaX 0.6.0

Choose a tag to compare

@rafatahmed rafatahmed released this 23 Oct 22:19

The grower release: FlahaX becomes a tool a grower or agronomist can run without code
(flahax mix, flahax batch), plans the recipe and its pH reagent together, checks stock
solubility, and moves to Beta. No breaking API change (14 names added, none removed); Python 3.11
or newer, still with no runtime dependencies. Known limits: the full-screen flahax mix is alpha
(--plain always works; typing "à" on Windows swallows the next key, #127), solubility checks are
single-salt lower bounds, and there is no physical validation yet (#41).
Full notes.

Added

  • Troubleshooting for installing, upgrading and the full-screen flahax mix in the user guide and the README.
  • flahax mix: five steps (specification, water analysis, crop formula, fertilizers available, target pH) that save waters, formulas, product stores, acids and sessions under $FLAHAX_HOME (default ~/.flahax) and write a batch sheet for the grower, the agronomist or the full report; flahax mix sessions/NAME repeats a batch.
  • Full-screen flahax mix in a terminal, standard library only (#124): arrow keys, type-to-filter lists, tick lists, and Tanks, Nutrients and Notes views. --plain, scripts and pipes keep the line-by-line questions.
  • flahax batch: one formula and one water to batch-sheet.html, report.html and summary.json, with the pH plan (#79); --water-share blends a measured water with RO water (#84).
  • Recipe and pH reagent planned together (plan_coupled_ph), with pH-up reagents (#74-#77).
  • Sourced stock solubility for 20 products (CRC Handbook, Yara, U.S. Coast Guard CHRIS), checked at the stock temperature.
  • Materials defined by what they put in the water (material_chemistry): a chemical formula, its ions, or a supplier analysis.
  • Public API: plan_coupled_ph, reagent_dose, catalogue_ph_reagents, PhAdjustmentPlan, PhCandidate, material_chemistry, group_tanks, default_compatibility_rules, TankGrouping, ConcentrateTank, TankProduct, summarize_batch, render_report, render_batch_sheet.
  • An error-code reference in the user guide covering all 91 codes, checked by a test.
  • SECURITY.md, a code of conduct (Contributor Covenant 2.1), Codecov coverage, README status badges, and CI on Windows and macOS (#150).
  • A draft physical-validation protocol (#41) and the Irriblend-DSW optimiser in the competitor benchmark (#40).

Changed

  • The documentation site is organised for its readers (Diátaxis): Get started, a grower, an agronomist and a developer and researcher guide, Reference (command line, Python API, input files, error codes), Explanation, Evidence and Project, with diagrams; moved pages redirect from their old addresses.
  • flahax --help describes every command, with examples and links to the documentation and the issue tracker; the README follows the order a reader needs (installation, quick start, commands, troubleshooting); the changelog follows Keep a Changelog 1.1.0 for every release.
  • Supplier labels may differ from their chemical's charge balance by up to 1 % (was 0.1 %) (#93).
  • A water report without chloride closes its charge balance on alkalinity instead of being blocked (#100).
  • Concentration limits and targets use the laboratory water analysis; the charge-balanced water is for chemistry only (#84).
  • Untargeted nutrients are assessed once, with the products that supply them; ammonium keeps the 10 % allowance, shown with its source (#92).
  • Phases that do not form at feed conditions (hydroxylapatite, goethite, MnHPO4, vivianite) make a plan requires_review with the reason, instead of rejecting it (#78).
  • The growers page is a task path with a worked example that a test re-runs (#80).
  • Development status Beta; Python 3.14 supported; maintainers, affiliation, a full NOTICE of data sources and verified references in CITATION.cff.
  • Code style: PEP 8 at 99 columns enforced in CI, file headers, and docstrings on every public definition (#120-#122).

Fixed

  • recommend() raised "NNLS did not reach optimality" when the water alone exceeded one declared maximum while another was binding (#86).
  • Bad input at any entry point, or a damaged session file, gives a plain message instead of a traceback (#117, #149).
  • First field tests of flahax mix: the formula list (#98), the start screen and --version (#102), saved sessions and small weights (#105), unknown acid formulas (#112), repeated notes (#113) and titles (#114).
  • Every output of one batch agrees: pH path, weights, acid volume and notes on the terminal, sheet and report (#107-#110).
  • The owner's trial of the full-screen mode: Windows arrow keys (#135), readable key help (#137), confirm before leaving (#138), filter and tick keys (#139), number display (#140), wrapping (#141), grower words (#142), and #125-#132, #143-#147.
  • The 0.5.0 manual and changelog kept the release-candidate wording; publishing now has a finalize step before tagging (#71).

Install

python -m pip install flahax==0.6.0

Documentation: https://flahax.readthedocs.io/ · Full notes: https://github.com/rafatahmed/Flahax/blob/v0.6.0/docs/releases/0.6.0.md · All changes: v0.5.0...v0.6.0

FlahaX 0.5.0

Choose a tag to compare

@rafatahmed rafatahmed released this 20 Oct 23:47
  • Publish Benchmark v1 snapshot 2026-10-20-linux-df0d30b (hosted run 39515183621 on main, after #62, #65 and #69), the first with every correctness gate passing: 7/7 controlled NNLS cases, 21/21 stored chemistry comparisons, 17/17 timing workloads; complete recipes 34/52 (was 29/52). The results page no longer calls a fully passing scorecard 'not fully passing' (#66).
  • Fix recommend() slowness and start-dependent recipes under incidental-ion ceilings (#68). Two root causes, both measured against SciPy on every fit: the NNLS optimality test used one tolerance scaled by the whole matrix (max |A| times |b|), so a heavily weighted row hid real descent directions in the other columns and NNLS stopped early (doses off by up to 4.2e-3 g/L); it now bounds each column's dual weight by the rounding error of its own terms. And a binding ceiling was enforced by a 1024-weight penalty, which left the problem so flat in double precision that doses were fixed only to ~2e-3 g/L and depended on the solver's starting point. A binding ceiling is now a constraint: a weight-8 row whose aim is shifted by the Lagrange multiplier, found by a bracketed secant search, with one Gram cache per search. Every ceiling fit now matches SciPy to 1.4e-10 g/L, warm and cold starts agree to 7e-9 g/L, and binding ions land on their aim. Over the 52 benchmark recipes recommend() is 34% faster with the default ammonium limit (4.20 -> 2.78 s) and unchanged with a 3 mmol/L Cl ceiling (3.77 -> 3.87 s); the Benchmark v1 formulation workload falls from about 30 to 16 ms. Pass counts are unchanged by default (34/52 recipes, 571/636 targets) and rise with the Cl ceiling (41 -> 42 recipes, 598 -> 599 targets), with no limit violations; the 10 recipes that change have equal or better target fit.
  • Fix Benchmark v1 measuring no timings after #63 (#64). ASV imports every module under benchmarks/ with only that package importable, and the competitor harness there imported tools, so discovery aborted. The harness moves to tools/competitors/, and a test now discovers the suite the way ASV does.
  • Speed up equilibrium solves 3-5x and their pH and dose searches 10-25x in pure Python (#61), found by the #40 comparison with PHREEQC. Each solve averaged its ionic-strength update and needed about 35 outer passes to reach |dI| < 1e-12; ionic strength now takes a safeguarded secant step (the average remains the fallback) and water activity plain substitution. solve(..., start=result) warm-starts from a nearby state (free-ion activities, ionic strength, water, precipitated phases) and falls back to the unchanged cold start if it fails; the nitric-target, calculated-pH, acid-selection and measured-water searches warm-start from their previous solve. Converged states are unchanged within solver tolerance (species within 7e-10 relative on every PHREEQC fixture; calculated pH within its 1e-7 bisection width). The mixed-product nitric target drops from about 1080 to 73 ms (PHREEQC: 4.5 ms), calculated-pH irrigation EC from 0.9-2.6 s to 74-244 ms per recipe, the test suite from 133 to 40 s. The shipped phosphate conductivity coefficients are unchanged; refitting them now reproduces them to 7.4e-9 relative instead of bit-exactly, so the reproduction test bounds coefficients at 1e-7 relative and percentages at 1e-5 points (owner decision).
  • recommend() is 2.8-4.0x faster in pure Python with identical recipes (#59). NNLS was 97% of its time: about 44 solves per call, each rebuilding a Householder factorisation over every row. Simplification trials now warm-start NNLS from the current solution, passive-set least squares use Cholesky on a lazily cached Gram matrix (Householder fallback and refinement when ill-conditioned), dual weights come from the cached Gram entries, and the miss diagnosis computes each drop-one fit once. Over the 52 benchmark cases (best of three, same machine): 248 -> 89 ms with the default ammonium limit, 297 -> 95 ms with a Cl ceiling, 146 -> 36 ms without ceilings. Every recipe is unchanged (largest final concentration change 3e-11 mg/L, identical product sets). Zero runtime dependencies are kept.
  • Fix the equilibrium solver failing to converge between pH 4.2 and 5.05 for chelate-rich mixed solutions (#52). From the cold start (every free activity at total/1000), Newton crawled toward strongly complexed free ions (EDTA, DTPA and EDDHA with Fe and Cu) until its iteration limit; an acid target of pH 5.0 for the mixed-product fixture failed. A failed solve now restarts from a continued-fraction mass-balance estimate (Wigley 1977). A pH 4-9 scan of the three mixed fixtures (1,503 solves) goes from 215 failures to none; converging solves are unchanged because the restart runs only after a failure.
  • The NNLS solver raises InputError when it is still not optimal at its iteration cap, instead of silently returning a non-optimal fit (#55). No benchmark fit reaches the cap.
  • recommend() reports targetIonBalance, the cation and anion meq/L implied by the formula (P as H2PO4-, S as SO4 2-), and warns when the sums differ by more than 10%. Eight shipped formulas exceed it, which explains most recipe misses (#39); for example Pepper (Howard Resh) is -39.5% and the U of Florida tomato clusters are +19% to +30%.
  • recommend() reports unmetTargets: each positive target missed by more than 1% with a reason (no_source, limited_by_ceiling, incidental_tradeoff, conflicting_targets with the conflicting targets, and whether chloride products would reach it) (#39). The 1% tolerance is documented as a FlahaX assumption.
  • Incidental-ion ceilings reach their limit in one refit instead of up to 13 (#56): mean recommend() time on the benchmark falls from 482 to 211 ms with the ammonium default.
  • plan_fertilizer_workflow notes a target pH outside the 5.3-5.8 feed range of Dutch soilless practice, or outside 5.0-7.0. The equilibrium acid plan reports the residual bicarbonate at the target pH and warns below the 0.5 mmol/L buffer Dutch practice leaves.
  • recommend() now allows incidental NH4-N up to the smaller of 10% of the formula's total target N and 1.5 mmol/L (21.01 mg/L N) when the targets omit N_NH4 (#54). Calcium nitrate (ag grade) always carries ammonium, so the penalty-only fit under-dosed calcium even where a recipe meeting every target existed (7 benchmark cases; 5 now pass, and Generic Grow needs more ammonium than the limit allows). Values are owner decisions based on Dutch soilless practice: NH4 at 5-15% of total N, at most 1-1.5 mmol/L (De Kreij, Voogt et al.; Voogt 'max 90:10'). result["ammoniumLimit"] reports the limit; max_ammonium_fraction raises it and None restores the previous fit; an explicit N_NH4 target, including 0, is unchanged. Whole-recipe passes rise from 29 to 34 of 52 benchmark cases (targets 563 -> 571 of 636), with no limit violations.
  • Speed up the equilibrium solver and its searches (#37) with numerically equivalent results (largest change across all PHREEQC fixtures: 6e-12 relative in species, 4e-13 in the nitric dose). The Jacobian and component sums now use each species' non-zero stoichiometry instead of every component (94% of runtime). The nitric-target, acid-option and alkalinity-to-carbon searches share one bracketed Illinois root finder with the same stopping rules as before, in place of fixed bisections. The calculated-pH search keeps its bisection, so the shipped phosphate conductivity fit (#37) reproduces exactly. The mixed-product nitric target fell from 44 solves and about 70 s to 12 solves and under 2 s (median 1.6 s) on the recording laptop. Benchmark v1 adds track_search_solves, which reports the solves per call.
  • Fix the equilibrium solver raising 'line search stalled' at some valid states: after a cold start a near-singular Jacobian (seen with Fe-EDDHA in the mixed-product solution at pH 7.396) gave an unusable Newton step. A damped least-squares (Levenberg-Marquardt) step now recovers. It runs only where the solver previously failed, so converging solves are unchanged.
  • Add Potassium Chloride (KCl) and Calcium Chloride (Dihydrate) (CaCl2.2H2O) to the catalogue (30 products), with identity-theoretical assays (K 52.4469 / Cl 47.5531 %; Ca 27.2626 / Cl 48.2289 %) sourced to Sigma-Aldrich P3911 and 223506. Calcium chloride is the first calcium source without nitrate (#39). Chloride needs consent: neither product is used unless the caller targets Cl, allows it (allow_ions) or sets a Cl maximum, so no default recipe changes.
  • Record the ChemicalBook technical data sheets (revision 2026-04-16, SHA-256 recorded) as sources for Ammonium Sulfate and Urea; they confirm identity and purity (laboratory grade). Assays are unchanged.
  • recommend(..., maximum_concentrations={...}) and plan_fertilizer_workflow now use incidental-ion ceilings in the fit: an ion with a positive ceiling (for example {"Cl": 70}) is admitted, is not penalised up to the ceiling, and is pulled back when the fit exceeds it. Any remaining excess is reported in limitViolations with feasible false. Without ceilings the result is unchanged.
  • Fix chloride handling in catalogue chemistry conversion: chloride assays were dropped from analytical totals, and a calcium salt was assumed to carry nitrate. Chlorine now uses 35.45 g/mol everywhere (previously 35.453 in water-ion conversions); the manual's Shomar et al. station 104 example now closes chloride by -9.53 % (was -9.52 %).
  • Fix early stopping in the NNLS solver (#36). Its optimality test used a fixed 1e-10 threshold, so near-dependent or very small-scale problems stopped before the optimum (Benchmark v1 near_dependent: objective 1.5e-12 instead of ~0; a problem scaled by 1e-8 returned all zeros). The optimality test is now at round-off level and scaled by the problem, rank checks are relative to column size, and a column rejected as dependent no longer blocks the others. All 1,266 NNLS problems solved for the 52 benchmark recipes match SciPy as before,...
Read more

FlahaX 0.4.0

Choose a tag to compare

@rafatahmed rafatahmed released this 17 Oct 15:00

FlahaX 0.4.0 is the first open-source release, under the Apache License 2.0.

Highlights:

  • Measured-pH water balancing. balance_water_analysis speciates a laboratory water analysis at its measured pH and closes the analysis's charge imbalance on Cl⁻ or Na⁺, recording the adjustment, instead of letting a few percent of analytical error become a pH error of several units. The workflow's equilibrium record accepts measured_ph.
  • Fully backward compatible with 0.3.1: all 100 public exports and their signatures are unchanged; 3 exports added.
  • Hardened, reviewer-gated release workflow with PyPI Trusted Publishing.
python -m pip install flahax==0.4.0

Changes

  • Relicense FlahaX under the Apache License 2.0 and add a NOTICE file. Releases up to and including 0.3.1 remain under the Flaha Free Use License 1.0.
  • Add balance_water_analysis: speciate a laboratory water analysis at its measured pH, take inorganic carbon from the analysis or from titrated alkalinity, and close the remaining charge on Cl- or Na+ with the imbalance and adjustment recorded. Imbalances above 5% (configurable) are rejected. The workflow's equilibrium record accepts measured_ph and reports water_balance. Charge balance alone turned a 3.5% analytical imbalance on a published Qatar well into a 4-unit pH error.
  • Add publication drafts under docs/publication/ (JOSS paper, field-trial article, story piece in English and Arabic, worked example); they are excluded from the source distribution.
  • Add the author's ORCID to CITATION.cff.
  • Harden the release workflow: a GitHub Release uploads only when its tag matches the package version and that version is new on PyPI, after the full test matrix, clean installs and the live PHREEQC replay pass, and after reviewer approval, via PyPI Trusted Publishing.
  • Bring the documentation up to date with 0.3.1 and 0.4.0, and remove two unreferenced 0.2.0 images from docs/ (and so from the sdist).

FlahaX 0.3.1

Choose a tag to compare

@rafatahmed rafatahmed released this 17 Oct 14:54

Published to PyPI on 2026-10-17 (manual Twine upload from 586eddb). This GitHub Release note was added afterwards; the release workflow skips versions already on PyPI, so nothing was re-uploaded.

Released under the Flaha Free Use License 1.0. From 0.4.0, FlahaX is open source under Apache-2.0.

0.3.0 was yanked the same day because its source distribution contained a third-party PDF. Use 0.3.1 or later.

Changes

  • Reframe the README, package summary and citation around FlahaX as a plant-nutrient chemistry engine (planned for FlahaFAST, not yet integrated); harden .gitignore, .gitattributes and the distribution PDF leak check.

  • Exclude the user-supplied YaraVita micronutrient guide from Git tracking and the source distribution, matching the other manufacturer PDFs; its SHA-256 is recorded in the source review. The published 0.3.0 sdist still contains it.

  • Ship a complete generated public API inventory, expand the manual to seven executable examples, and check documentation drift in source and installed-package tests. Clarify product-dose mapping after recommendation filtering, stage statuses and unpublished-version installation.

  • Clarify every pepper product's candidate Tank A/B/acid destination or unresolved status; display actual contents of synthetic stock examples, preserve recipe mass and prevent interpreting recipe acid as an additional pH dose.

  • Document current capability limits and next steps; preserve supplied manufacturer PDFs locally while excluding them from versioned/package artifacts and retaining reviewed source hashes.

  • Add interactive/JSON workflow, EC-screening and injector-sizing CLI commands; retain the legacy stdin contract. Require explicit source water and restrict standard workflow acids to nitric/phosphoric, preserving lower-level scientific references.

  • Review four supplied fertilizer PDFs; add exact-SQM-brand pre-acid EC screening with unknown accuracy and unsupported-stock boundaries, plus channel volume/flow requirements for pump, venturi and Dosatron sizing. No fabricated equipment model selection.

  • Add an offline HTML capability report with accessible SVG charts, explicit units and nutrient/chemistry/acid/EC/injection tables; keep synthetic evidence and missing-input statuses visible.

  • Add recipe-calibrated EC25 estimation for separate concentrated stock tanks and combined irrigation solution, explicit meter-TDS conversion, and recipe-preserving injection/pump planning. Missing calibration never yields a fabricated EC value; no real calibration dataset or universal concentrated-stock predictor is claimed.

  • Add runnable examples/ capability scenarios and a combined JSON/Markdown report, with explicit synthetic-data boundaries and regression coverage; include examples in source distributions.

  • Separate zero-target incidental nutrients from positive-target fit and explicit maximum concentrations; preserve real catalogue materials.

  • Add explicit source-water-to-formulation orchestration, complete-analysis calculated pH, measured-curve/stock delegation and single-acid candidate planning for nitric, phosphoric, sulfuric and citric acids.

  • Add four charge-balanced PHREEQC acid references with hashes, conservation/equivalence tests and live replay. These development APIs are not in the published 0.3.0 artifacts; see docs/water-to-delivery.md for assumptions and input requirements.

Evidence: 0.3.1 publication record.

FlahaX 0.3.0

Choose a tag to compare

@rafatahmed rafatahmed released this 01 Oct 05:36

FlahaX 0.3.0

Historical GitHub release record for the package published to PyPI on
2026-09-27. This GitHub record is being added on 2026-10-01; it is
not a new PyPI upload or a backdated GitHub publication.

Included capabilities

  • Fertilizer formulation with source-water nutrient subtraction.
  • One bounded mixed-equilibrium model covering 28 catalogue products,
    197 aqueous entries and 28 phases.
  • Fe-only DTPA and o,o-EDDHA catalogue forms, declared EDTA products and CH-micro.
  • Nitric-acid target-pH and assay-qualified equilibrium-to-delivery planning.
  • Sourced stock planning, measured-curve pH and calibrated pump-planning APIs.
  • A shipped user manual, PHREEQC reference evidence and clean-install checks.

Runtime requirements: Python 3.11 or newer, no mandatory third-party Python
dependencies. PHREEQC is a separate verification tool, not bundled software.

Scientific and release boundaries

The coupled model is limited to 25 C, Davies ionic strength at or below
0.1 mol/kg water, fixed oxidation states and the declared analytical/phase
boundary. Planning results are not autonomous dosing instructions, operational
certification or universal concentrated-stock predictions.

The owner authorized the original 0.3.0 PyPI publication using local evidence
despite the GitHub Actions billing blocker. That exception does not mean hosted
checks passed and does not apply automatically to later releases. Computational
assessment is attributed to Rafat Al Khashan; independent laboratory evidence
or a personal signature is not claimed.

The newer site-input CLI, EC-screening and graphical-report work belongs to
0.3.1 preparation and is not included in this release.

Source provenance

Tag v0.3.0 identifies commit
96ce35ce151f21d660db80f4a54ea1af74e9dc42.

The published sdist was compared with Git's archive of that revision:
279 tracked packaged files matched, normalizing CRLF/LF only. The two
workflow files are not shipped in the sdist. Additional sdist files are only
generated package metadata. All 30 wheel package files also matched the
sdist source, with the same line-ending normalization. Other examined source
revisions differed in the shipped release documentation.

Original published artifacts

The release assets are the exact archives downloaded from PyPI, not rebuilt
copies from the current branch. Both passed twine check --strict and match
PyPI's SHA-256 values:

File SHA-256
flahax-0.3.0-py3-none-any.whl fde10f04bdb3f222d2a3eb0dc6c77dbd4393a2f3257dc94a02f4182bbe997309
flahax-0.3.0.tar.gz 33298d8a206653b52d1ecf2df5cddd6ed1c4a4f7cf179ecb46348d9558a8dfd0

Original PyPI upload times (UTC): wheel 2026-09-27T20:50:59.149437Z;
sdist 2026-09-27T20:51:01.402309Z.

The existing local dist/0.3.0-final/ files have different archive hashes and
were not used as release assets. No local archives or evidence were deleted.

Install the existing published package:

python -m pip install flahax==0.3.0

PyPI 0.3.0 |
Source revision

FlahaX 0.2.0

Choose a tag to compare

@rafatahmed rafatahmed released this 25 Sep 15:54

One salt library, assay checks, and input validation. Carbonate, sodium, and chloride stay out of a default recipe unless the formula asks for them or the caller allows them. Published to PyPI as flahax 0.2.0.

FlahaX 0.1.0

Choose a tag to compare

@rafatahmed rafatahmed released this 25 Sep 15:01

First public package. FlahaX chooses fertilizer salts and grams per litre for a fixed crop formula. Use is free under the Flaha Free Use License, which does not allow modification or redistribution.