Skip to content

Add histological staining area quantification workflow#1206

Draft
dianichj wants to merge 3 commits intogalaxyproject:mainfrom
dianichj:histological-staining-quantification-workflow
Draft

Add histological staining area quantification workflow#1206
dianichj wants to merge 3 commits intogalaxyproject:mainfrom
dianichj:histological-staining-quantification-workflow

Conversation

@dianichj
Copy link
Copy Markdown
Member

@dianichj dianichj commented Apr 9, 2026

This workflow quantifies the area of histological staining in brightfield
histological images using colour deconvolution and automated thresholding.
Compatible with Masson's Trichrome (MT) and Immunohistochemistry (IHC).

Published workflow: https://usegalaxy.eu/u/dianitachj24/w/histological-staining-area-quantification

Status

Draft PR - test data and .dockstore.yml will be added before final merge.

  • test-data to Zenodo (files > 100 KB)
  • CHANGELOG.md
  • .dockstore.yml

cc: @mvdbeek @afgane

@mvdbeek mvdbeek requested a review from Copilot April 9, 2026 12:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a Galaxy workflow to quantify histological staining area in brightfield images using colour deconvolution + thresholding, along with accompanying documentation and a workflow test definition.

Changes:

  • Added the “Histological Staining Area Quantification” Galaxy workflow (.ga) with steps for deconvolution, channel selection, thresholding, feature extraction, and result collation.
  • Added a workflow test YAML describing a multi-sample input collection and expected outputs.
  • Added a README describing inputs/outputs and compatible stainings.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 10 comments.

File Description
workflows/imaging/histological-staining-area-quantification/histological-staining-area-quantification.ga Introduces the full staining-quantification workflow and output collation steps.
workflows/imaging/histological-staining-area-quantification/histological-staining-area-quantification-test.yml Adds a test definition for running the workflow on a collection of ROI images and checking outputs.
workflows/imaging/histological-staining-area-quantification/README.md Documents workflow purpose, inputs/outputs, and compatible stain/channel assumptions.

"workflow_outputs": []
},
"11": {
"annotation": "Applies a threshold to the selected stain channel to segment stained areas for quantification.\nTool only process tiff files with 1 channel. ",
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

The PR description (and workflow narrative) says the workflow uses Li thresholding, but the configured threshold method here is Otsu (method_id: otsu). This changes the core segmentation behavior. Either switch the workflow configuration to Li (if intended) or update the PR description/readme/annotations to reflect Otsu to keep the published method consistent.

Copilot uses AI. Check for mistakes.
"owner": "imgteam",
"tool_shed": "toolshed.g2.bx.psu.edu"
},
"tool_state": "{\"input\": {\"__class__\": \"RuntimeValue\"}, \"invert_output\": false, \"th_method\": {\"method_id\": \"otsu\", \"__current_case__\": 1, \"offset\": \"0.0\"}, \"__page__\": 0, \"__rerun_remap_job_id__\": null}",
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

The PR description (and workflow narrative) says the workflow uses Li thresholding, but the configured threshold method here is Otsu (method_id: otsu). This changes the core segmentation behavior. Either switch the workflow configuration to Li (if intended) or update the PR description/readme/annotations to reflect Otsu to keep the published method consistent.

Copilot uses AI. Check for mistakes.
Comment on lines +1230 to +1236
"workflow_outputs": [
{
"label": "Tabular File: Staining Feature Results",
"output_name": "out_file1",
"uuid": "1c3f7fd0-bad7-4891-9f95-f1346e44c20f"
}
]
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

The workflow computes percent_area in step 27, but step 27 is not exposed as a workflow output (workflow_outputs is empty). This makes the documented percent_area result unavailable to workflow consumers. Mark step 27 (or the appropriate downstream dataset that includes percent_area) as a workflow output, and adjust the test expectations accordingly.

Copilot uses AI. Check for mistakes.
"type": "tool",
"uuid": "ae102451-2b3c-4ede-89db-a18e52b7bb2a",
"when": null,
"workflow_outputs": []
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

The workflow computes percent_area in step 27, but step 27 is not exposed as a workflow output (workflow_outputs is empty). This makes the documented percent_area result unavailable to workflow consumers. Mark step 27 (or the appropriate downstream dataset that includes percent_area) as a workflow output, and adjust the test expectations accordingly.

Suggested change
"workflow_outputs": []
"workflow_outputs": [
{
"label": "percent_area",
"output_name": "out_file1",
"uuid": "2d53a6f8-0a7e-4c55-9f52-cfdff8e6267e"
}
]

Copilot uses AI. Check for mistakes.
Comment on lines +23 to +26
| Staining | Target channel |
|----------|---------------|
| Masson's Trichrome (MT) | Channel 2 |
| Immunohistochemistry (IHC) | Channel 2 (DAB) |
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

The markdown table is malformed (uses || at line starts), which may render incorrectly. Use standard markdown table syntax with single leading/trailing | per row so the table renders reliably.

Copilot uses AI. Check for mistakes.
Comment on lines +832 to +833
"label": "Extract",
"name": "Select last",
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

The workflow selects the last row from each per-sample feature table before collapsing. For binary masks, feature extraction commonly yields multiple labels (e.g., background=0 and stained=1). Relying on row order is brittle and can select the wrong label if ordering changes. Prefer filtering explicitly on the label column (e.g., keep only label == 1) before collapsing, or configure the feature-extraction step to output only the target label if the tool supports it.

Copilot uses AI. Check for mistakes.
},
"post_job_actions": {},
"tool_id": "Show tail1",
"tool_state": "{\"header\": false, \"input\": {\"__class__\": \"ConnectedValue\"}, \"lineNum\": \"1\", \"__page__\": 0, \"__rerun_remap_job_id__\": null}",
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

The workflow selects the last row from each per-sample feature table before collapsing. For binary masks, feature extraction commonly yields multiple labels (e.g., background=0 and stained=1). Relying on row order is brittle and can select the wrong label if ordering changes. Prefer filtering explicitly on the label column (e.g., keep only label == 1) before collapsing, or configure the feature-extraction step to output only the target label if the tool supports it.

Copilot uses AI. Check for mistakes.
Comment on lines +75 to +119
path: 'test-data/Collection: Individual Deconvolved Channels_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_3.tiff.tiff'
control_2:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_3.tiff.tiff'
control_3:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_3.tiff.tiff'
treatment_1:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_3.tiff.tiff'
treatment_2:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_3.tiff.tiff'
treatment_3:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_3.tiff.tiff'
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

Several element_tests reuse the same expected output files across different input samples (e.g., control_2 points to the same deconvolved-channel golden files as control_1). Unless the inputs are identical, this will either fail once real test data is added or will mask regressions if comparisons are unintentionally satisfied. Recommend providing per-sample golden outputs (or switching to more robust assertions for images/tabular outputs if exact matches are not feasible).

Suggested change
path: 'test-data/Collection: Individual Deconvolved Channels_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_3.tiff.tiff'
control_2:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_3.tiff.tiff'
control_3:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_3.tiff.tiff'
treatment_1:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_3.tiff.tiff'
treatment_2:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_3.tiff.tiff'
treatment_3:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_3.tiff.tiff'
path: 'test-data/Collection: Individual Deconvolved Channels_control_1_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_control_1_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_control_1_3.tiff.tiff'
control_2:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_control_2_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_control_2_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_control_2_3.tiff.tiff'
control_3:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_control_3_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_control_3_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_control_3_3.tiff.tiff'
treatment_1:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_treatment_1_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_treatment_1_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_treatment_1_3.tiff.tiff'
treatment_2:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_treatment_2_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_treatment_2_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_treatment_2_3.tiff.tiff'
treatment_3:
elements:
1.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_treatment_3_1.tiff.tiff'
2.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_treatment_3_2.tiff.tiff'
3.tiff:
path: 'test-data/Collection: Individual Deconvolved Channels_treatment_3_3.tiff.tiff'

Copilot uses AI. Check for mistakes.
"workflow_outputs": []
},
"1": {
"annotation": "Add Sample ID column name .",
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

Fix minor grammar/typos in step annotations to improve readability (e.g., remove the extra space before the period in "name ." and change "Tool only process" to "Tool only processes").

Suggested change
"annotation": "Add Sample ID column name .",
"annotation": "Add Sample ID column name.",

Copilot uses AI. Check for mistakes.
"workflow_outputs": []
},
"11": {
"annotation": "Applies a threshold to the selected stain channel to segment stained areas for quantification.\nTool only process tiff files with 1 channel. ",
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

Fix minor grammar/typos in step annotations to improve readability (e.g., remove the extra space before the period in "name ." and change "Tool only process" to "Tool only processes").

Suggested change
"annotation": "Applies a threshold to the selected stain channel to segment stained areas for quantification.\nTool only process tiff files with 1 channel. ",
"annotation": "Applies a threshold to the selected stain channel to segment stained areas for quantification.\nTool only processes TIFF files with 1 channel.",

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants