Overview
NonLinearSearch.perform_update (~155 lines) and perform_visualization (~80 lines) in abstract_search.py mix multiple concerns: sample persistence, latent sample computation, visualization, profiling, timing, and summary output. Extract these into a new SearchUpdater class to achieve separation of concerns, where each output task is its own focused method. Search-type-specific behavior (MCMC vs nested sampling plots) uses composition via a callable.
Follow-up to #1003 (closed without implementation).
Plan
- Create
SearchUpdater class in autofit/non_linear/search/updater.py with focused methods for each output concern
- Decompose
perform_update into: _update_iteration_state, _save_samples, _compute_latent_samples, _profile_and_summarize
- Move
perform_visualization into SearchUpdater.visualize
- Use composition for
plot_results — passed as callable, no parallel inheritance hierarchy needed
- Keep thin delegators on
NonLinearSearch for backward compatibility
- No changes to any search subclass (emcee, zeus, dynesty, nautilus, bfgs)
Detailed implementation plan
Affected Repositories
Work Classification
Library
Branch Survey
| Repository |
Current Branch |
Dirty? |
| ./PyAutoFit |
main |
clean |
Suggested branch: feature/search-update-refactor
Worktree root: ~/Code/PyAutoLabs-wt/search-update-refactor/ (created later by /start_library)
Implementation Steps
-
Create autofit/non_linear/search/updater.py with SearchUpdater class (~180 lines)
- Constructor receives:
paths, timer, logger, plot_results_func, samples_from_func, should_profile, disable_output, iterations_per_full_update
update() — main orchestrator (replaces perform_update body)
visualize() — visualization (replaces perform_visualization body)
_update_iteration_state() — increment counter, update timer
_save_samples() — sample persistence
_compute_latent_samples() — latent sample logic
_profile_and_summarize() — profiling + summary output
_log_process_state() — static method, moved from NonLinearSearch
iterations property (read/write)
-
Modify autofit/non_linear/search/abstract_search.py
- Add lazy
_updater property that constructs SearchUpdater on first access
- Replace
perform_update body (~155 lines) with 3-line delegator to self._updater.update(...)
- Replace
perform_visualization body (~80 lines) with 3-line delegator to self._updater.visualize(...)
- Wire
self.iterations through the updater object
- Net reduction: ~220 lines
Key Files
autofit/non_linear/search/abstract_search.py — main refactoring target
autofit/non_linear/search/updater.py — new file
autofit/non_linear/mock/mock_search.py — overrides perform_update, no changes needed
autofit/non_linear/search/mcmc/abstract_mcmc.py — plot_results override, no changes needed
autofit/non_linear/search/nest/abstract_nest.py — plot_results override, no changes needed
autofit/non_linear/search/mle/abstract_mle.py — plot_results override, no changes needed
Edge Cases
MockSearch.perform_update fully overrides — continues to work, never touches SearchUpdater
plot_start_point calls perform_visualization(paths_override=...) — handled by delegator
paths reference sharing — lazy construction mitigates; invalidate if paths reassigned
Original Prompt
Click to expand starting prompt
Issue Move search update to new class #1003 — Extract SearchUpdate class: perform_update and perform_visualization in abstract_search.py interact with many modules (saving samples, visualization, profiling, outputting results). Extracting to a SearchUpdate class would make each output task its own method.
#1003
Do an assessment of if this is a good idea and if so come up with an example of th eimplementtation. I think its clear
abstract_search needs to be simplified and have a better sense of separation of concerns.
The goal here is really to achieve seapration of concerns in abstract_search.py and move these different categories of output
results to dediciated modules. A benefit is that some of these, like samples, are tied to the type of
search (e.g. mcmc, nested sampling). So the type of output can mayb eexploit composition or stronger typing
to make the work more clear and explicit.
Overview
NonLinearSearch.perform_update(~155 lines) andperform_visualization(~80 lines) inabstract_search.pymix multiple concerns: sample persistence, latent sample computation, visualization, profiling, timing, and summary output. Extract these into a newSearchUpdaterclass to achieve separation of concerns, where each output task is its own focused method. Search-type-specific behavior (MCMC vs nested sampling plots) uses composition via a callable.Follow-up to #1003 (closed without implementation).
Plan
SearchUpdaterclass inautofit/non_linear/search/updater.pywith focused methods for each output concernperform_updateinto:_update_iteration_state,_save_samples,_compute_latent_samples,_profile_and_summarizeperform_visualizationintoSearchUpdater.visualizeplot_results— passed as callable, no parallel inheritance hierarchy neededNonLinearSearchfor backward compatibilityDetailed implementation plan
Affected Repositories
Work Classification
Library
Branch Survey
Suggested branch:
feature/search-update-refactorWorktree root:
~/Code/PyAutoLabs-wt/search-update-refactor/(created later by/start_library)Implementation Steps
Create
autofit/non_linear/search/updater.pywithSearchUpdaterclass (~180 lines)paths,timer,logger,plot_results_func,samples_from_func,should_profile,disable_output,iterations_per_full_updateupdate()— main orchestrator (replacesperform_updatebody)visualize()— visualization (replacesperform_visualizationbody)_update_iteration_state()— increment counter, update timer_save_samples()— sample persistence_compute_latent_samples()— latent sample logic_profile_and_summarize()— profiling + summary output_log_process_state()— static method, moved from NonLinearSearchiterationsproperty (read/write)Modify
autofit/non_linear/search/abstract_search.py_updaterproperty that constructsSearchUpdateron first accessperform_updatebody (~155 lines) with 3-line delegator toself._updater.update(...)perform_visualizationbody (~80 lines) with 3-line delegator toself._updater.visualize(...)self.iterationsthrough the updater objectKey Files
autofit/non_linear/search/abstract_search.py— main refactoring targetautofit/non_linear/search/updater.py— new fileautofit/non_linear/mock/mock_search.py— overridesperform_update, no changes neededautofit/non_linear/search/mcmc/abstract_mcmc.py—plot_resultsoverride, no changes neededautofit/non_linear/search/nest/abstract_nest.py—plot_resultsoverride, no changes neededautofit/non_linear/search/mle/abstract_mle.py—plot_resultsoverride, no changes neededEdge Cases
MockSearch.perform_updatefully overrides — continues to work, never touchesSearchUpdaterplot_start_pointcallsperform_visualization(paths_override=...)— handled by delegatorpathsreference sharing — lazy construction mitigates; invalidate if paths reassignedOriginal Prompt
Click to expand starting prompt
Issue Move search update to new class #1003 — Extract SearchUpdate class: perform_update and perform_visualization in abstract_search.py interact with many modules (saving samples, visualization, profiling, outputting results). Extracting to a SearchUpdate class would make each output task its own method.
#1003
Do an assessment of if this is a good idea and if so come up with an example of th eimplementtation. I think its clear
abstract_search needs to be simplified and have a better sense of separation of concerns.
The goal here is really to achieve seapration of concerns in abstract_search.py and move these different categories of output
results to dediciated modules. A benefit is that some of these, like samples, are tied to the type of
search (e.g. mcmc, nested sampling). So the type of output can mayb eexploit composition or stronger typing
to make the work more clear and explicit.