3. Algorithm Extraction

After framework and domain logic separation, the next step is algorithm extraction. The purpose is to refactor the code so the algorithm is defined in plain functions or small classes that contain no framework code and can be tested independently.

This means separating the code into two parts:

Algorithm part

Contains the domain logic. It should operate on plain C++ values, experiment-specific data structures, and explicitly provided helper objects, without framework callbacks, event objects, handles, services, or registration machinery.

Framework-dependent part

Contains configuration lookup, input retrieval, helper construction, registration, and output publication.

The algorithm part should answer the question “what computation is being performed?” The framework part should answer “how is this computation wired into the framework?” A good extraction leaves the algorithm usable in an ordinary unit test or standalone driver without bringing in framework code.

This is the key structural change that makes migration to Phlex practical. Without it, migration remains a translation of framework-specific code. With it, migration becomes a matter of binding clear inputs and outputs to a well-defined computation. The extracted algorithm can then be tested and compared against the original implementation.

Because many original modules have limited test coverage, extraction should minimize changes to the core logic while moving framework-specific code into a separate boundary layer.

A successful extraction produces code with the following properties:

  • The algorithm is defined in plain functions or small classes.

  • The algorithm can be called from ordinary C++.

  • The algorithm does not depend on module callbacks such as produce() or analyze().

  • The algorithm contains no direct framework code.

  • Configuration is gathered once and passed explicitly.

  • Input products are passed in as parameters.

  • Output products are returned as values.

  • Remaining framework assumptions are visible and localized.

3.2. What May Stay in the Algorithm Temporarily

A migration can proceed even if the algorithm still contains some transitional framework assumptions, as long as those assumptions are visible and localized.

In the gauss_hit_finder example, comments explicitly mark temporary limitations around geometry support and comparison-oriented output. That is a reasonable intermediate state. The important point is that such concerns are not hidden behind deep framework coupling.

3.3. Algorithm Extraction Checklist

Before moving on to Phlex binding, verify the following.

  1. Can the core algorithm be described without mentioning framework callbacks?

  2. Are all real inputs represented in the function signature or constructor?

  3. Are all outputs represented as return values or explicit output objects?

  4. Is configuration collected outside the algorithm?

  5. Are remaining framework assumptions documented as transitional issues?

3.4. Common Extraction Mistakes

The following patterns usually indicate that extraction is incomplete.

  • A helper class still reaches into framework state because that was convenient in the original module.

  • Configuration parsing remains spread across several helper objects.

  • Service access remains hidden inside low-level logic.

  • The new code preserves the old module structure even when the algorithm itself is much simpler.

The goal is not to preserve familiar structure. It is to expose the real computation cleanly enough that it can be expressed in Phlex.