Skip to content

Ylim down#131

Merged
tonywu1999 merged 2 commits intodevelfrom
ylimDown
Apr 25, 2026
Merged

Ylim down#131
tonywu1999 merged 2 commits intodevelfrom
ylimDown

Conversation

@tonywu1999
Copy link
Copy Markdown
Contributor

@tonywu1999 tonywu1999 commented Apr 25, 2026

Motivation and Context

This PR modifies the default behavior for the ylimDown parameter in the dataProcessPlotsPTM function, which controls the lower y-axis limit for Profile and QC plots. Previously, when ylimDown was not explicitly specified (default FALSE), plots automatically used a lower limit of 0. This change implements a data-driven lower limit calculation that adapts to the actual intensity ranges in the dataset, specifically using the minimum log2-transformed abundance value (log2 intensity) minus 3, floored and clamped at 0 to prevent negative axis limits.

Changes Made

  • Documentation Updates (R/dataProcessPlotsPTM.R and generated man/dataProcessPlotsPTM.Rd):

    • Updated the ylimDown parameter documentation to describe the new default behavior: "floor of minimum log2(intensities) after normalization - 3, or 0 if that value is negative"
  • Core Logic Implementation (R/utils_dataProcessPlots.R):

    • Modified four internal plotting functions (.profile.tmt, .qc.tmt, .profile.lf, .qc.lf) to compute y.limdown dynamically when ylimDown is not provided as a numeric value
    • When ylimDown = FALSE (default), the new calculation is: y.limdown = max(floor(min(all_abund, na.rm = TRUE) - 3), 0)
    • The all_abund vector includes both PTM and protein abundances when protein/global data is present, otherwise only PTM abundances
    • When ylimDown is explicitly provided as a numeric value, the behavior remains unchanged (uses the provided value)
  • Package Documentation (man/MSstatsPTM.Rd):

    • Added a new "Useful links" entry pointing to the project website (https://vitek-lab.github.io/MSstatsPTM/)
  • Minor Punctuation Fix: One commit addresses a minor punctuation issue

Unit Tests

No new unit tests were added or modified to verify these changes. The existing test suite (inst/tinytest/) contains tests for data summarization, conversion utilities, and parameter validation checks, but does not include tests for the plotting functionality (dataProcessPlotsPTM, ProfilePlot, or QCPlot).

Coding Guidelines Violations

Minor inconsistencies in code style:

  • Ternary-style if expressions: The code uses all_abund = if (condition) value1 else value2 syntax, which is unconventional for R style (more common in functional programming languages). This pattern is applied consistently across all four modified functions but may not align with traditional R coding guidelines that typically prefer explicit conditional statements.

  • Inconsistent protocol detection: Different functions use different methods to detect whether protein data is present: some use plot_global variable while others use length(data.table.list) == 4. Both approaches are functionally equivalent but represent inconsistent code patterns within the same file.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 25, 2026

📝 Walkthrough

Walkthrough

Updates y-axis limit calculation for Profile/QC plots from hardcoded zeros to data-dependent values computed as floor(min(log2(intensities)) - 3) with fallback to zero. Changes affect plot rendering logic and corresponding documentation.

Changes

Cohort / File(s) Summary
ylimDown parameter documentation
R/dataProcessPlotsPTM.R, man/dataProcessPlotsPTM.Rd
Updated parameter documentation to describe new default calculation: floor(min(log2(intensities)) - 3) with fallback to 0 when negative, replacing previous constant zero default.
Plot y-axis limit computation
R/utils_dataProcessPlots.R
Implemented data-dependent lower y-axis limit logic in TMT and LF profile/QC wrapper functions. Computes y.limdown from minimum ABUNDANCE values across datasets (PTM only or PTM+protein) when ylimDown parameter is not provided numerically.
Package documentation link
man/MSstatsPTM.Rd
Added project website URL to "Useful links" section in package documentation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Poem

🐰 The plots now see with sharper eyes,
No more the zeros' tired disguise!
With data-driven bounds so bright,
The y-axis finds its perfect height! 📊✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Ylim down' is overly vague and uses a generic term without conveying meaningful information about the specific change or its purpose. Provide a more descriptive title such as 'Update ylimDown default calculation for plot y-axis limits' to clearly communicate the main change.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description provides comprehensive motivation, detailed changes across multiple files, and acknowledges testing gaps. All required template sections are present and substantive.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ylimDown

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
man/MSstatsPTM.Rd (1)

1-2: ⚠️ Potential issue | 🔴 Critical

Revert this edit to man/MSstatsPTM.Rd and add the URL to R/MSstatsPTM.R instead.

This file is auto-generated by roxygen2 and must not be edited manually. The header explicitly directs you to edit R/MSstatsPTM.R. Manual changes will be lost when documentation is regenerated.

To properly add the website URL:

  1. Add it to the roxygen2 comments in R/MSstatsPTM.R (in a @seealso section)
  2. Run roxygen2::roxygenize() to regenerate man/MSstatsPTM.Rd
  3. Commit the updated R/MSstatsPTM.R and man/MSstatsPTM.Rd (auto-generated by roxygen2)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@man/MSstatsPTM.Rd` around lines 1 - 2, Revert the manual edits to
man/MSstatsPTM.Rd (restore the version generated by roxygen2) and instead add
the website URL into the roxygen comments of R/MSstatsPTM.R (for example in a
`@seealso` block or other appropriate roxygen tag), then run
roxygen2::roxygenize() to regenerate man/MSstatsPTM.Rd and commit the updated
R/MSstatsPTM.R and the auto-generated man/MSstatsPTM.Rd; do not edit the .Rd
file by hand.
🧹 Nitpick comments (3)
R/utils_dataProcessPlots.R (2)

875-880: Minor inconsistency: gate uses length(data.table.list) == 4 here but plot_global in the profile wrappers.

.profile.tmt (Line 556) and .profile.lf (Line 1380) gate the same c(ptm, protein) decision on plot_global, while .qc.tmt (Line 878) and .qc.lf (Line 1677) re-derive it from length(data.table.list) == 4. Functionally equivalent today, but it would be cleaner to compute plot_global once near the top of each wrapper (before this block) and use it consistently — either as part of the helper suggested above, or by hoisting the existing plot_global = length(...) == 4 assignment up. That avoids future drift if one branch changes how "global protein data is present" is determined.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@R/utils_dataProcessPlots.R` around lines 875 - 880, Compute and reuse a
single boolean "plot_global" flag instead of re-checking length(data.table.list)
== 4 in multiple places: add a plot_global <- (length(data.table.list) == 4)
near the top of each wrapper (.profile.tmt, .qc.tmt, .profile.lf, .qc.lf) and
replace the inline checks (e.g., the expression used when building all_abund)
with that plot_global variable so both c(ptm, protein) gating and other branches
consistently use plot_global.

553-558: Recommended refactor: extract the duplicated y.limdown auto-calculation into a small helper.

The same two-line all_abund / floor(min(...) - 3) pattern is repeated in .profile.tmt (Lines 553-558), .qc.tmt (Lines 875-880), .profile.lf (Lines 1377-1382), and .qc.lf (Lines 1674-1679). Centralizing it would keep the four wrappers in lock-step if the formula ever changes (e.g., switching the -3 margin or the clamp), and would make the intent named/searchable.

♻️ Example helper
# `@noRd`
.compute.ylim.down = function(ylimDown, ptm_abund, protein_abund = NULL) {
  if (is.numeric(ylimDown)) return(ylimDown)
  all_abund = if (!is.null(protein_abund)) c(ptm_abund, protein_abund) else ptm_abund
  if (!length(all_abund) || all(is.na(all_abund))) return(0)
  max(floor(min(all_abund, na.rm = TRUE) - 3), 0)
}

Then each wrapper becomes a single call, e.g.:

-  if (is.numeric(ylimDown)) {
-    y.limdown = ylimDown
-  } else {
-    all_abund = if (plot_global) c(datafeature.ptm$ABUNDANCE, datafeature.protein$ABUNDANCE) else datafeature.ptm$ABUNDANCE
-    y.limdown = max(floor(min(all_abund, na.rm = TRUE) - 3), 0)
-  }
+  y.limdown = .compute.ylim.down(
+    ylimDown,
+    datafeature.ptm$ABUNDANCE,
+    if (plot_global) datafeature.protein$ABUNDANCE else NULL
+  )

As a side effect this also handles the edge case where all_abund is empty or all-NA (currently min(..., na.rm = TRUE) would emit a warning and return Inf, producing y.limdown = Inf).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@R/utils_dataProcessPlots.R` around lines 553 - 558, Extract the duplicated
y.limdown auto-calculation into a small helper (e.g. .compute.ylim.down) and
replace the repeated blocks in .profile.tmt, .qc.tmt, .profile.lf and .qc.lf
with a single call to that helper; the helper should accept ylimDown, ptm_abund
and optional protein_abund, return ylimDown immediately if numeric, combine ptm
and protein abundance when provided, handle empty/all-NA vectors by returning 0,
and otherwise compute max(floor(min(all_abund, na.rm = TRUE) - 3), 0) so callers
like the code that previously set y.limdown follow the same behavior without
duplication.
R/dataProcessPlotsPTM.R (1)

31-33: Doc update reads correctly and matches the implementation.

The new ylimDown default description aligns with max(floor(min(all_abund, na.rm = TRUE) - 3), 0) in R/utils_dataProcessPlots.R.

One small nit: in .format.data.process.plots, ABUNDANCE is taken either from INTENSITY (with log2() applied) or from already-logged columns like LOGINTENSITIES / LOG2INTENSITY (lines 91-98 of R/utils_dataProcessPlots.R), so calling them strictly "log2(intensities)" is slightly imprecise for the LOGINTENSITIES path. Consider "minimum log-intensity" to cover both cases.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@R/dataProcessPlotsPTM.R` around lines 31 - 33, Update the wording for
ylimDown to use "minimum log-intensity" instead of "minimum log2(intensities)"
to accurately reflect that ABUNDANCE in .format.data.process.plots is derived
either by log2(INTENSITY) or taken from already-logged columns (LOGINTENSITIES /
LOG2INTENSITY); change the param description in R/dataProcessPlotsPTM.R and any
related user-facing docs to mention "minimum log-intensity" so it covers both
paths, referencing .format.data.process.plots and the ABUNDANCE assignment
logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@man/MSstatsPTM.Rd`:
- Around line 1-2: Revert the manual edits to man/MSstatsPTM.Rd (restore the
version generated by roxygen2) and instead add the website URL into the roxygen
comments of R/MSstatsPTM.R (for example in a `@seealso` block or other appropriate
roxygen tag), then run roxygen2::roxygenize() to regenerate man/MSstatsPTM.Rd
and commit the updated R/MSstatsPTM.R and the auto-generated man/MSstatsPTM.Rd;
do not edit the .Rd file by hand.

---

Nitpick comments:
In `@R/dataProcessPlotsPTM.R`:
- Around line 31-33: Update the wording for ylimDown to use "minimum
log-intensity" instead of "minimum log2(intensities)" to accurately reflect that
ABUNDANCE in .format.data.process.plots is derived either by log2(INTENSITY) or
taken from already-logged columns (LOGINTENSITIES / LOG2INTENSITY); change the
param description in R/dataProcessPlotsPTM.R and any related user-facing docs to
mention "minimum log-intensity" so it covers both paths, referencing
.format.data.process.plots and the ABUNDANCE assignment logic.

In `@R/utils_dataProcessPlots.R`:
- Around line 875-880: Compute and reuse a single boolean "plot_global" flag
instead of re-checking length(data.table.list) == 4 in multiple places: add a
plot_global <- (length(data.table.list) == 4) near the top of each wrapper
(.profile.tmt, .qc.tmt, .profile.lf, .qc.lf) and replace the inline checks
(e.g., the expression used when building all_abund) with that plot_global
variable so both c(ptm, protein) gating and other branches consistently use
plot_global.
- Around line 553-558: Extract the duplicated y.limdown auto-calculation into a
small helper (e.g. .compute.ylim.down) and replace the repeated blocks in
.profile.tmt, .qc.tmt, .profile.lf and .qc.lf with a single call to that helper;
the helper should accept ylimDown, ptm_abund and optional protein_abund, return
ylimDown immediately if numeric, combine ptm and protein abundance when
provided, handle empty/all-NA vectors by returning 0, and otherwise compute
max(floor(min(all_abund, na.rm = TRUE) - 3), 0) so callers like the code that
previously set y.limdown follow the same behavior without duplication.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a1abe8c0-ed7d-45b8-a6c3-c49c8eaf44a2

📥 Commits

Reviewing files that changed from the base of the PR and between f7cde3b and 002a2d4.

📒 Files selected for processing (4)
  • R/dataProcessPlotsPTM.R
  • R/utils_dataProcessPlots.R
  • man/MSstatsPTM.Rd
  • man/dataProcessPlotsPTM.Rd

@tonywu1999 tonywu1999 merged commit 34354a2 into devel Apr 25, 2026
3 checks passed
@tonywu1999 tonywu1999 deleted the ylimDown branch April 25, 2026 15:30
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.

1 participant