ForeFire writes almost everything to stdout, with no severity levels, so diagnostics and simulation data share one stream. Repo-wide: 299 cout << against 28 cerr <<, concentrated in Command.cpp (78/18), FireDomain.cpp (38/9) and DataBroker.cpp (30/0).
A fully passing unit-test run prints 34 lines beginning with ERROR — to stdout — while stderr stays empty:
4 ERROR: vector of parameters SO2.hours should be valued
4 ERROR: vector of parameters FFfluxes.mCoeffs should be valued
2 ERROR: vector of parameters lava.windTresholds should be valued
None is an error: instantiating a flux model without its optional parameters is normal, and every test passes. A real failure would print in the same format on the same stream, indistinguishable.
Simulation output shares the stream with diagnostics. runff writes thousands of lines like
FireNode[domain=0;id=1422;fdepth=20;kappa=0.047331;loc=(35632.5,28535.6,81.155);…]
where a warning would go. Any script parsing that output has to filter, and cannot tell "the simulation said this" from "the library complained about this".
Suggested fix
A minimal logging facility — level (error/warning/info/debug), a runtime threshold, errors and warnings on stderr. Not a dependency; a small header is enough. The mechanical part is reclassifying the 299 call sites, mostly obvious from the message text, and good incremental work.
Worth doing before the ensemble work rather than around it: 500 simulations logging at today's verbosity to stdout is unusable. It also stops ERROR: being used for conditions that are neither errors nor exceptional, which currently trains everyone to ignore it.
Related: #164 (C++17) would allow std::source_location for file/line context — not required, but cheaper if done after.
Drafted by Claude Opus 5 from a codebase audit. Reviewed by a maintainer before filing.
EDIT: rewrote for human readability.
ForeFire writes almost everything to
stdout, with no severity levels, so diagnostics and simulation data share one stream. Repo-wide: 299cout <<against 28cerr <<, concentrated inCommand.cpp(78/18),FireDomain.cpp(38/9) andDataBroker.cpp(30/0).A fully passing unit-test run prints 34 lines beginning with
ERROR— to stdout — while stderr stays empty:None is an error: instantiating a flux model without its optional parameters is normal, and every test passes. A real failure would print in the same format on the same stream, indistinguishable.
Simulation output shares the stream with diagnostics.
runffwrites thousands of lines likewhere a warning would go. Any script parsing that output has to filter, and cannot tell "the simulation said this" from "the library complained about this".
Suggested fix
A minimal logging facility — level (error/warning/info/debug), a runtime threshold, errors and warnings on
stderr. Not a dependency; a small header is enough. The mechanical part is reclassifying the 299 call sites, mostly obvious from the message text, and good incremental work.Worth doing before the ensemble work rather than around it: 500 simulations logging at today's verbosity to stdout is unusable. It also stops
ERROR:being used for conditions that are neither errors nor exceptional, which currently trains everyone to ignore it.Related: #164 (C++17) would allow
std::source_locationfor file/line context — not required, but cheaper if done after.Drafted by Claude Opus 5 from a codebase audit. Reviewed by a maintainer before filing.
EDIT: rewrote for human readability.