Skip to content

Conversation

@alejoe91
Copy link
Member

This PR improves the extension dependency management system.
New class methods for the base AnalyzerExtension give more flexibility, by allowing dependencies to be specified at runtime based on the extension params:

cls.get_required_extensions(**params)

cls.get_optional_extension(**params)

The compute_several_extension and _sort_extensions_by_dependency will only use the required extension.
Optional extensions are used though to further organize the computation as follows.
Extensions are split into 3 groups:

  • pre_pipeline: extensions that to not depend on pipeline nodes and are run before
  • with_pipeline: extensions that can be run toghether in a with run_node_pipeline
  • post_pipeline: extensions whose any dependency (required or optional) depend on a pipeline node extension

This new organization allows us to remove the quality metric hack! In the current state, quality metrics were always run as post pipeline because some of them may depend on spike amplitudes/locations. Now, depending on the metric list, quality metrics (and other extensions!) will be moved post pipeline if needed:

See this in effect with some debug prints:
image

@alejoe91 alejoe91 added the core Changes to core module label Jan 15, 2026
print(f"Error casting column {col}: {e}")
return metrics_df
@classmethod
def get_optional_dependencies(cls, **params):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For BaseMetricExtensions, optional dependencies will include all dependencies for metrics. These are not required, because if a a metric doesn't meet its dependencies it's skipped in the _set_params


# make a copy of extensions
# note that the copy of extension handle itself the slicing of units when necessary and also the saveing
sorted_extensions = _sort_extensions_by_dependency(self.extensions)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorting here was not needed, because the compute_several_extensions already does all the checks and sorting required!

Comment on lines 1791 to 1794
elif any(
get_extension_class(d).use_nodepipeline
for d in extension_class.get_all_dependencies(**extension_params)
if d in sorted_extensions
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any extension whose dependencies use node pipeline are moved to the end

Comment on lines +2051 to +2060
for dependency in required_dependencies:
if "|" in dependency:
for dep in dependency.split("|"):
if extension not in _extension_children[dep]:
print(f"Adding missing dependency child link: {dep} -> {extension}")
_extension_children[dep].append(extension)
else:
if extension not in _extension_children[dependency]:
print(f"Adding missing dependency child link: {dependency} -> {extension}")
_extension_children[dependency].append(extension)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If an extension is not a child of another extension by default, but it becomes one based on parameters, we add it to the extension children

# run fine if dependency computed
sorting_analyzer.compute(["dummy", "dummy_pipeline"], extension_params=dict(dummy_pipeline=dict(param0=11)))


Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add test: if recompute dummy, dummy_pipeline should be deleted.

@alejoe91
Copy link
Member Author

@samuelgarcia this is good to go! I renamed the function and added the extra test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Changes to core module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant