Skip to content

Commit

Permalink
Generate metrics based on decision tree (#969)
Browse files Browse the repository at this point in the history
* Get required metrics from decision tree.

* Continue changes.

* More updates.

* Store necessary_metrics as a list.

* Update selection_nodes.py

* Update selection_utils.py

* Update across the package.

* Keep updating.

* Update tedana.py

* Add extra metrics to list.

* Update ica_reclassify.py

* Run black.

* Address style issues.

* Try fixing test bugs.

* Update test_component_selector.py

* Update component_selector.py

* Use component table directly in selectcomps2use.

* Fix.

* Include generated metrics in necessary metrics.

* Update component_selector.py

* Update component_selector.py

* Update test_component_selector.py

* fixed some testing failures

* fixed test_check_null_succeeds

* fixed ica_reclassify bug and selector_properties test

* ComponentSelector initialized before loading data

* fixed docstrings

* updated building decision tree docs

* Update docs/building_decision_trees.rst

Co-authored-by: Taylor Salo <[email protected]>

* Update tedana/selection/selection_utils.py

Co-authored-by: Taylor Salo <[email protected]>

* Update tedana/selection/selection_utils.py

Co-authored-by: Taylor Salo <[email protected]>

* Update tedana/selection/selection_utils.py

---------

Co-authored-by: handwerkerd <[email protected]>
Co-authored-by: Dan Handwerker <[email protected]>
  • Loading branch information
3 people authored Mar 20, 2024
1 parent a21d65e commit 9cbd484
Show file tree
Hide file tree
Showing 11 changed files with 613 additions and 623 deletions.
24 changes: 11 additions & 13 deletions docs/building_decision_trees.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ The file key names are used below the full file names in the
General outputs from component selection
========================================

New columns in ``selector.component_table`` and the "ICA metrics tsv" file:
New columns in ``selector.component_table_`` and the "ICA metrics tsv" file:

- classification:
While the decision table is running, there may also be intermediate
Expand All @@ -63,13 +63,13 @@ New columns in ``selector.component_table`` and the "ICA metrics tsv" file:
or a comma separated list of tags. These tags may be useful parameters
for visualizing and reviewing results

``selector.cross_component_metrics`` and "ICA cross component metrics json":
``selector.cross_component_metrics_`` and "ICA cross component metrics json":
A dictionary of metrics that are each a single value calculated across components,
for example, kappa and rho elbows. User or pre-defined scaling factors are
also stored here. Any constant that is used in the component classification
processes that isn't pre-defined in the decision tree file should be saved here.

``selector.component_status_table`` and "ICA status table tsv":
``selector.component_status_table_`` and "ICA status table tsv":
A table where each column lists the classification status of
each component after each node was run. Columns are only added
for runs where component statuses can change.
Expand Down Expand Up @@ -210,11 +210,9 @@ that is used to check whether results are plausible & can help avoid mistakes.

- necessary_metrics
A list of the necessary metrics in the component table that will be used
by the tree. If a metric doesn't exist then this will raise an error instead
of executing a tree. (Depending on future code development, this could
potentially be used to run ``tedana`` by specifying a decision tree and
metrics are calculated based on the contents of this field.) If a necessary
metric isn't used, there will be a warning.
by the tree. This field defines what metrics will be calculated on each ICA
component. If a metric doesn't exist then this will raise an error instead
of executing a tree. If a necessary metric isn't used, there will be a warning.

- generated_metrics
An optional initial field. It lists metrics that are to be calculated as
Expand Down Expand Up @@ -315,7 +313,7 @@ are good examples for how to meet these expectations.

Create a dictionary called "outputs" that includes key fields that should be recorded.
The following line should be at the end of each function to retain the output info:
``selector.nodes[selector.current_node_idx]["outputs"] = outputs``
``selector.nodes[selector.current_node_idx_]["outputs"] = outputs``

Additional fields can be used to log function-specific information, but the following
fields are common and may be used by other parts of the code:
Expand All @@ -339,7 +337,7 @@ Before any data are touched in the function, there should be an
call. This will be useful to gather all metrics a tree will use without requiring a
specific dataset.

Existing functions define ``function_name_idx = f"Step {selector.current_node_idx}: [text of function_name]``.
Existing functions define ``function_name_idx = f"Step {selector.current_node_idx_}: [text of function_name]``.
This is used in logging and is cleaner to initialize near the top of each function.

Each function has code that creates a default node label in ``outputs["node_label"]``.
Expand Down Expand Up @@ -378,15 +376,15 @@ dataframe column that is True or False for the components in ``decide_comps`` ba
the function's criteria.
That column is an input to :func:`~tedana.selection.selection_utils.change_comptable_classifications`,
which will update the component_table classifications, update the classification history
in component_status_table, and update the component classification_tags. Components not
in ``selector.component_status_table_``, and update the component classification_tags. Components not
in ``decide_comps`` retain their existing classifications and tags.
:func:`~tedana.selection.selection_utils.change_comptable_classifications`
also returns and should assign values to
``outputs["n_true"]`` and ``outputs["n_false"]``. These log how many components were
identified as true or false within each function.

For calculation functions, the calculated values should be added as a value/key pair to
both ``selector.cross_component_metrics`` and ``outputs``.
both ``selector.cross_component_metrics_`` and ``outputs``.

:func:`~tedana.selection.selection_utils.log_decision_tree_step`
puts the relevant info from the function call into the program's output log.
Expand All @@ -395,7 +393,7 @@ Every function should end with:

.. code-block:: python
selector.nodes[selector.current_node_idx]["outputs"] = outputs
selector.nodes[selector.current_node_idx_]["outputs"] = outputs
return selector
functionname.__doc__ = (functionname.__doc__.format(**DECISION_DOCS))
Expand Down
2 changes: 1 addition & 1 deletion tedana/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ def writeresults(ts, mask, comptable, mmix, io_generator):
========================================= ===========================================
Filename Content
========================================= ===========================================
desc-denoised_bold.nii.gz Denoised time series.
desc-denoised_bold.nii.gz Denoised time series.
desc-optcomAccepted_bold.nii.gz High-Kappa time series. (only with verbose)
desc-optcomRejected_bold.nii.gz Low-Kappa time series. (only with verbose)
Expand Down
Loading

0 comments on commit 9cbd484

Please sign in to comment.