-
Notifications
You must be signed in to change notification settings - Fork 1
feat: integrate LFQ and TMT workflows #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5,7 +5,8 @@ | |||||
| from scipy.cluster.hierarchy import linkage, leaves_list | ||||||
| from scipy.spatial.distance import pdist | ||||||
| from src.common.common import page_setup | ||||||
| from src.common.results_helpers import get_abundance_data | ||||||
| from src.common.results_helpers import get_abundance_data, get_workflow_dir | ||||||
| from src.workflow.ParameterManager import ParameterManager | ||||||
|
|
||||||
| params = page_setup() | ||||||
| st.title("Heatmap") | ||||||
|
|
@@ -29,48 +30,103 @@ | |||||
|
|
||||||
| pivot_df, expr_df, group_map = result | ||||||
|
|
||||||
| top_n = st.slider("Number of proteins", 20, 200, 50, key="heatmap_top_n") | ||||||
| workflow_dir = get_workflow_dir(st.session_state["workspace"]) | ||||||
| parameter_manager = ParameterManager(workflow_dir, "TOPP Workflow") | ||||||
|
|
||||||
| var_series = expr_df.var(axis=1) | ||||||
| top_proteins = var_series.sort_values(ascending=False).head(top_n).index | ||||||
| heatmap_df = expr_df.loc[top_proteins] | ||||||
| heatmap_z = heatmap_df.sub(heatmap_df.mean(axis=1), axis=0).div(heatmap_df.std(axis=1), axis=0) | ||||||
| heatmap_z = heatmap_z.replace([np.inf, -np.inf], np.nan).dropna() | ||||||
| workflow_params = parameter_manager.get_parameters_from_json() | ||||||
| analysis_mode = workflow_params.get("analysis-mode", "LFQ") | ||||||
|
|
||||||
| if not heatmap_z.empty: | ||||||
| row_linkage = linkage(pdist(heatmap_z.values), method="average") | ||||||
| row_order = leaves_list(row_linkage) | ||||||
| st.write("Workflow Analysis Mode:", analysis_mode) | ||||||
|
|
||||||
| col_linkage = linkage(pdist(heatmap_z.T.values), method="average") | ||||||
| col_order = leaves_list(col_linkage) | ||||||
| if analysis_mode == "LFQ": | ||||||
| top_n = st.slider("Number of proteins", 20, 200, 50, key="heatmap_top_n") | ||||||
|
|
||||||
| heatmap_clustered = heatmap_z.iloc[row_order, col_order] | ||||||
| var_series = expr_df.var(axis=1) | ||||||
| top_proteins = var_series.sort_values(ascending=False).head(top_n).index | ||||||
| heatmap_df = expr_df.loc[top_proteins] | ||||||
| heatmap_z = heatmap_df.sub(heatmap_df.mean(axis=1), axis=0).div(heatmap_df.std(axis=1), axis=0) | ||||||
| heatmap_z = heatmap_z.replace([np.inf, -np.inf], np.nan).dropna() | ||||||
|
|
||||||
| fig_heatmap = px.imshow( | ||||||
| heatmap_clustered, | ||||||
| labels=dict(x="Sample", y="Protein", color="Z-score"), | ||||||
| aspect="auto", | ||||||
| color_continuous_scale=[[0.0, "#3b6fb6"], [0.5, "white"], [1.0, "#b40426"]], | ||||||
| zmin=-3, zmax=3 | ||||||
| ) | ||||||
| if not heatmap_z.empty: | ||||||
| row_linkage = linkage(pdist(heatmap_z.values), method="average") | ||||||
| row_order = leaves_list(row_linkage) | ||||||
|
|
||||||
| fig_heatmap.update_layout( | ||||||
| height=700, | ||||||
| xaxis={'side': 'bottom'}, | ||||||
| yaxis={'side': 'left'} | ||||||
| ) | ||||||
| col_linkage = linkage(pdist(heatmap_z.T.values), method="average") | ||||||
| col_order = leaves_list(col_linkage) | ||||||
|
|
||||||
| fig_heatmap.update_xaxes(tickfont=dict(size=10)) | ||||||
| fig_heatmap.update_yaxes(tickfont=dict(size=8)) | ||||||
| heatmap_clustered = heatmap_z.iloc[row_order, col_order] | ||||||
|
|
||||||
| st.plotly_chart(fig_heatmap, use_container_width=True) | ||||||
| fig_heatmap = px.imshow( | ||||||
| heatmap_clustered, | ||||||
| labels=dict(x="Sample", y="Protein", color="Z-score"), | ||||||
| aspect="auto", | ||||||
| color_continuous_scale=[[0.0, "#3b6fb6"], [0.5, "white"], [1.0, "#b40426"]], | ||||||
| zmin=-3, zmax=3 | ||||||
| ) | ||||||
|
|
||||||
| fig_heatmap.update_layout( | ||||||
| height=700, | ||||||
| xaxis={'side': 'bottom'}, | ||||||
| yaxis={'side': 'left'} | ||||||
| ) | ||||||
|
|
||||||
| fig_heatmap.update_xaxes(tickfont=dict(size=10)) | ||||||
| fig_heatmap.update_yaxes(tickfont=dict(size=8)) | ||||||
|
|
||||||
| st.plotly_chart(fig_heatmap, use_container_width=True) | ||||||
| else: | ||||||
| st.warning("Insufficient data to generate the heatmap.") | ||||||
|
|
||||||
| st.markdown("---") | ||||||
| st.markdown("**Other visualizations:**") | ||||||
| col1, col2 = st.columns(2) | ||||||
| with col1: | ||||||
| st.page_link("content/results_volcano.py", label="Volcano Plot", icon="🌋") | ||||||
| with col2: | ||||||
| st.page_link("content/results_pca.py", label="PCA", icon="📊") | ||||||
| else: | ||||||
| st.warning("Insufficient data to generate the heatmap.") | ||||||
|
|
||||||
| st.markdown("---") | ||||||
| st.markdown("**Other visualizations:**") | ||||||
| col1, col2 = st.columns(2) | ||||||
| with col1: | ||||||
| st.page_link("content/results_volcano.py", label="Volcano Plot", icon="🌋") | ||||||
| with col2: | ||||||
| st.page_link("content/results_pca.py", label="PCA", icon="📊") | ||||||
| top_n = st.slider("Number of proteins", 20, 200, 50, key="heatmap_top_n") | ||||||
|
|
||||||
| var_series = expr_df.var(axis=1) | ||||||
| top_proteins = var_series.sort_values(ascending=False).head(top_n).index | ||||||
| heatmap_df = expr_df.loc[top_proteins] | ||||||
| heatmap_z = heatmap_df.sub(heatmap_df.mean(axis=1), axis=0).div(heatmap_df.std(axis=1), axis=0) | ||||||
| heatmap_z = heatmap_z.replace([np.inf, -np.inf], np.nan).dropna() | ||||||
|
|
||||||
| if not heatmap_z.empty: | ||||||
| row_linkage = linkage(pdist(heatmap_z.values), method="average") | ||||||
| row_order = leaves_list(row_linkage) | ||||||
|
|
||||||
| col_linkage = linkage(pdist(heatmap_z.T.values), method="average") | ||||||
| col_order = leaves_list(col_linkage) | ||||||
|
|
||||||
| heatmap_clustered = heatmap_z.iloc[row_order, col_order] | ||||||
|
|
||||||
| fig_heatmap = px.imshow( | ||||||
| heatmap_clustered, | ||||||
| labels=dict(x="Sample", y="Protein", color="Z-score"), | ||||||
| aspect="auto", | ||||||
| color_continuous_scale=[[0.0, "#3b6fb6"], [0.5, "white"], [1.0, "#b40426"]], | ||||||
| zmin=-3, zmax=3 | ||||||
| ) | ||||||
|
|
||||||
| fig_heatmap.update_layout( | ||||||
| height=700, | ||||||
| xaxis={'side': 'bottom'}, | ||||||
| yaxis={'side': 'left'} | ||||||
| ) | ||||||
|
|
||||||
| fig_heatmap.update_xaxes(tickfont=dict(size=10)) | ||||||
| fig_heatmap.update_yaxes(tickfont=dict(size=8)) | ||||||
|
|
||||||
| st.plotly_chart(fig_heatmap, width="stretch") | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Invalid Same issue as other pages - Proposed fix- st.plotly_chart(fig_heatmap, width="stretch")
+ st.plotly_chart(fig_heatmap, use_container_width=True)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| else: | ||||||
| st.warning("Insufficient data to generate the heatmap.") | ||||||
|
|
||||||
| st.markdown("---") | ||||||
| st.markdown("**Other visualizations:**") | ||||||
| col1, col2 = st.columns(2) | ||||||
| with col1: | ||||||
| st.page_link("content/results_volcano.py", label="Volcano Plot", icon="🌋") | ||||||
| with col2: | ||||||
| st.page_link("content/results_pca.py", label="PCA", icon="📊") | ||||||
|
Comment on lines
+41
to
+132
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win Eliminate near-complete code duplication. The LFQ and non-LFQ branches (lines 41-86 vs 87-132) are nearly identical - the only difference is the chart rendering call. This should be a single code path. Proposed refactor-if analysis_mode == "LFQ":
- top_n = st.slider("Number of proteins", 20, 200, 50, key="heatmap_top_n")
- # ... 40+ lines of identical code ...
- st.plotly_chart(fig_heatmap, use_container_width=True)
- # ... footer links ...
-else:
- top_n = st.slider("Number of proteins", 20, 200, 50, key="heatmap_top_n")
- # ... 40+ lines of identical code ...
- st.plotly_chart(fig_heatmap, width="stretch")
- # ... footer links ...
+top_n = st.slider("Number of proteins", 20, 200, 50, key="heatmap_top_n")
+
+var_series = expr_df.var(axis=1)
+top_proteins = var_series.sort_values(ascending=False).head(top_n).index
+heatmap_df = expr_df.loc[top_proteins]
+heatmap_z = heatmap_df.sub(heatmap_df.mean(axis=1), axis=0).div(heatmap_df.std(axis=1), axis=0)
+heatmap_z = heatmap_z.replace([np.inf, -np.inf], np.nan).dropna()
+
+if not heatmap_z.empty:
+ # ... clustering and figure creation ...
+ st.plotly_chart(fig_heatmap, use_container_width=True)
+else:
+ st.warning("Insufficient data to generate the heatmap.")
+
+st.markdown("---")
+st.markdown("**Other visualizations:**")
+# ... links ...🤖 Prompt for AI Agents |
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
npis undefined - missing numpy import.The non-LFQ branch uses
np.log2()butnumpyis not imported in this file, causing aNameErrorat runtime when TMT mode is used.Proposed fix - add import at top of file
+import numpy as np from src.workflow.ParameterManager import ParameterManager🧰 Tools
🪛 GitHub Actions: Pylint / 0_build.txt
[error] 75-75: pylint E0602: Undefined variable 'np' (undefined-variable)
🪛 GitHub Actions: Pylint / build
[error] 75-75: pylint E0602: Undefined variable 'np' (undefined-variable)
🪛 Ruff (0.15.17)
[error] 75-75: Undefined name
np(F821)
🤖 Prompt for AI Agents
Source: Linters/SAST tools