Summary
Grouped small items, each cheap to fix now and expensive to fix after the API ossifies:
- Public API typo
reflectity_profile in calculator_base.py:192, factory.py:43, project.py:668 — rename to reflectivity_profile with a deprecation alias.
- LSP wrinkle:
Material.sld returns a Parameter while MaterialMixture.sld returns a float (material_mixture.py:159-165); both flow into Layer.material, so layer.material.sld.value works or crashes depending on material type. Return the Parameter consistently.
- No-op test assertions:
tests/model/test_resolution_functions.py:41, 70, 115-120 — assert resolution_function.as_dict(), {...} (comma, not comparison; always passes) and bare as_dict() == {...} expressions without assert.
mcmc_sample doc/API mismatch: the docstring (and bayesian.py:1335 load_posterior) advertises resume_state=, but fitting.py:358-437 has no such parameter — resume is either unimplemented or renamed.
ResolutionFunction uses @abstractmethod without ABC (resolution_functions.py:23-28) — abstractness not enforced.
Model.add_assemblies(*assemblies: list[BaseAssembly]) (model.py:151) — wrong annotation; each vararg is a BaseAssembly.
molecular_weight docstring claims kilograms (special/calculations.py:66); value is u (g/mol). In neutron_scattering_length (:47-51) the variable inc holds the imaginary/absorption part, not the incoherent length.
limits.py:33-41: percentage-based default limits produce inverted bounds (min > max) for negative values — latent, but unguarded.
Project.as_dict side effect: the fitter property lazily constructs a MultiFitter and switches minimizer (project.py:283-290, hit from :871); serialization should be pure. Similarly get_index_air/si/sio2/d2o (:349-371) append materials from a getter.
- Stray
pass at project.py:389; dead _flatten_list in fitting.py:499-512.
Found during deep code review (DEEP_ANALYSIS.md §3.1, §5, §7).
Summary
Grouped small items, each cheap to fix now and expensive to fix after the API ossifies:
reflectity_profileincalculator_base.py:192,factory.py:43,project.py:668— rename toreflectivity_profilewith a deprecation alias.Material.sldreturns aParameterwhileMaterialMixture.sldreturns afloat(material_mixture.py:159-165); both flow intoLayer.material, solayer.material.sld.valueworks or crashes depending on material type. Return theParameterconsistently.tests/model/test_resolution_functions.py:41, 70, 115-120—assert resolution_function.as_dict(), {...}(comma, not comparison; always passes) and bareas_dict() == {...}expressions withoutassert.mcmc_sampledoc/API mismatch: the docstring (andbayesian.py:1335load_posterior) advertisesresume_state=, butfitting.py:358-437has no such parameter — resume is either unimplemented or renamed.ResolutionFunctionuses@abstractmethodwithoutABC(resolution_functions.py:23-28) — abstractness not enforced.Model.add_assemblies(*assemblies: list[BaseAssembly])(model.py:151) — wrong annotation; each vararg is aBaseAssembly.molecular_weightdocstring claims kilograms (special/calculations.py:66); value is u (g/mol). Inneutron_scattering_length(:47-51) the variableincholds the imaginary/absorption part, not the incoherent length.limits.py:33-41: percentage-based default limits produce inverted bounds (min > max) for negative values — latent, but unguarded.Project.as_dictside effect: thefitterproperty lazily constructs aMultiFitterand switches minimizer (project.py:283-290, hit from:871); serialization should be pure. Similarlyget_index_air/si/sio2/d2o(:349-371) append materials from a getter.passatproject.py:389; dead_flatten_listinfitting.py:499-512.Found during deep code review (DEEP_ANALYSIS.md §3.1, §5, §7).