142 lines
5.8 KiB
R
142 lines
5.8 KiB
R
suppressPackageStartupMessages({
|
|
library(MALDIquant)
|
|
library(MALDIquantForeign)
|
|
library(ggplot2)
|
|
library(ggrepel)
|
|
library(dplyr)
|
|
library(stringr)
|
|
library(readr)
|
|
})
|
|
|
|
## ===================== Configuration =====================
|
|
# File paths
|
|
base_path <- "/home/sierra/Documentos/Analisis de datos/Analisis de datos R"
|
|
file_std <- file.path(base_path, "Fragmentos/Escopolamina_tuneo_fraq_20ev.mzML")
|
|
file_smp <- file.path(base_path, "Fragmentos/LD_LTP_MS_cot_fraq_304.mzML")
|
|
output_dir <- file.path(base_path, "Fragmentos/Resultados_MS2/Comparativos")
|
|
output_file <- file.path(output_dir, "Mirror_Plot_Scopolamine_304_Academic.png")
|
|
|
|
# Plotting parameters
|
|
mz_range <- c(80, 320)
|
|
label_threshold <- 0.05
|
|
topN_labels <- 8
|
|
dpi_png <- 300
|
|
bar_width_Da <- 0.2
|
|
|
|
# Preprocessing parameters
|
|
halfWindowSize <- 5
|
|
snr_peaks <- 2.0
|
|
tolerance_Da <- 0.02
|
|
|
|
## ===================== Utilities =====================
|
|
massSpectrum_to_df <- function(sp) data.frame(mz = mz(sp), intensity = intensity(sp))
|
|
|
|
# Refined centroid (intensity-weighted)
|
|
refine_centroid <- function(df, m0, w) {
|
|
sub <- df[df$mz >= (m0 - w) & df$mz <= (m0 + w), ]
|
|
if (nrow(sub) == 0) return(m0)
|
|
sum(sub$mz * sub$intensity) / sum(sub$intensity)
|
|
}
|
|
|
|
# Preprocessing pipeline for a single file (averaging scans if multiple exist)
|
|
process_file <- function(f) {
|
|
scans <- importMzMl(f)
|
|
if (length(scans) > 1) {
|
|
scans <- smoothIntensity(scans, method = "SavitzkyGolay", halfWindowSize = 7)
|
|
scans <- removeBaseline(scans, method = "SNIP", iterations = 60)
|
|
scans <- calibrateIntensity(scans, method = "TIC")
|
|
# Basic alignment if multiple scans
|
|
pks <- detectPeaks(scans, method = "MAD", halfWindowSize = halfWindowSize, SNR = 1.5)
|
|
ref <- referencePeaks(pks, minFrequency = 0.5, tolerance = tolerance_Da)
|
|
scans <- alignSpectra(scans, halfWindowSize = halfWindowSize, SNR = 1.5, tolerance = tolerance_Da, reference = ref)
|
|
spec_avg <- averageMassSpectra(scans, method = "mean")
|
|
} else {
|
|
spec_avg <- scans[[1]]
|
|
spec_avg <- smoothIntensity(spec_avg, method = "SavitzkyGolay", halfWindowSize = 7)
|
|
spec_avg <- removeBaseline(spec_avg, method = "SNIP", iterations = 60)
|
|
spec_avg <- calibrateIntensity(spec_avg, method = "TIC")
|
|
}
|
|
return(spec_avg)
|
|
}
|
|
|
|
# Label generation
|
|
make_labels <- function(spec, df, rel_threshold = 0.05, topN = 5, w = tolerance_Da) {
|
|
pk <- detectPeaks(spec, method = "MAD", halfWindowSize = halfWindowSize, SNR = snr_peaks)
|
|
if (length(pk) == 0) return(NULL)
|
|
|
|
lab_df <- data.frame(mz = mz(pk), intensity = intensity(pk))
|
|
lab_df$mz <- vapply(lab_df$mz, function(m) refine_centroid(df, m, w), numeric(1))
|
|
lab_df$rel_int <- lab_df$intensity / max(lab_df$intensity, na.rm = TRUE)
|
|
|
|
# Select top N and those above threshold
|
|
keep_idx <- unique(c(order(lab_df$rel_int, decreasing = TRUE)[seq_len(min(topN, nrow(lab_df)))],
|
|
which(lab_df$rel_int >= rel_threshold)))
|
|
lab_df <- lab_df[sort(keep_idx), ]
|
|
|
|
lab_df$label <- sprintf("%.2f", lab_df$mz)
|
|
return(lab_df)
|
|
}
|
|
|
|
## ===================== Execution =====================
|
|
message("Processing Scopolamine spectra...")
|
|
spec_std <- process_file(file_std)
|
|
spec_smp <- process_file(file_smp)
|
|
|
|
df_std <- massSpectrum_to_df(spec_std) %>% mutate(intensity = intensity / max(intensity))
|
|
df_smp <- massSpectrum_to_df(spec_smp) %>% mutate(intensity = intensity / max(intensity))
|
|
|
|
labels_std <- make_labels(spec_std, df_std, label_threshold, topN_labels)
|
|
labels_smp <- make_labels(spec_smp, df_smp, label_threshold, topN_labels)
|
|
|
|
# Prepare mirrored data
|
|
df_smp$y <- df_smp$intensity
|
|
df_std$y <- -df_std$intensity
|
|
df_smp$Group <- "Sample (Leaf)"
|
|
df_std$Group <- "Reference Standard"
|
|
|
|
# Combine for plotting
|
|
df_all <- bind_rows(df_smp, df_std)
|
|
|
|
# Filter by range
|
|
df_all <- df_all %>% filter(mz >= mz_range[1], mz <= mz_range[2])
|
|
|
|
message("Generating mirror plot...")
|
|
p <- ggplot() +
|
|
# Mirror spectra (lines)
|
|
geom_segment(data = df_smp %>% filter(mz >= mz_range[1], mz <= mz_range[2]),
|
|
aes(x = mz, xend = mz, y = 0, yend = y), color = "#1f77b4", linewidth = 0.3) +
|
|
geom_segment(data = df_std %>% filter(mz >= mz_range[1], mz <= mz_range[2]),
|
|
aes(x = mz, xend = mz, y = 0, yend = y), color = "#d62728", linewidth = 0.3) +
|
|
geom_hline(yintercept = 0, color = "black", linewidth = 0.5) +
|
|
|
|
# Labels
|
|
geom_text_repel(data = labels_smp, aes(x = mz, y = rel_int, label = label),
|
|
nudge_y = 0.05, size = 3.5, color = "#1f77b4", fontface = "bold",
|
|
max.overlaps = 20, min.segment.length = 0) +
|
|
geom_text_repel(data = labels_std, aes(x = mz, y = -rel_int, label = label),
|
|
nudge_y = -0.05, size = 3.5, color = "#d62728", fontface = "bold",
|
|
max.overlaps = 20, min.segment.length = 0) +
|
|
|
|
# English Academic Annotations
|
|
scale_y_continuous(labels = function(x) abs(x) * 100, limits = c(-1.15, 1.15),
|
|
breaks = seq(-1, 1, 0.5)) +
|
|
scale_x_continuous(limits = mz_range, breaks = seq(mz_range[1], mz_range[2], 20)) +
|
|
labs(title = expression(bold("MS/MS Spectrum Comparison: Scopolamine (") * bolditalic("m/z") * bold(" 304.17)")),
|
|
subtitle = "Upper: Scopolamine in Leaf (Sample) | Lower: Scopolamine Standard (Reference)\nCollision Energy: 20 eV",
|
|
x = expression(italic(m/z)),
|
|
y = "Relative Abundance (%)") +
|
|
theme_classic(base_size = 14) +
|
|
theme(
|
|
plot.title = element_text(face = "bold", hjust = 0.5),
|
|
plot.subtitle = element_text(hjust = 0.5, size = 11, lineheight = 1.2),
|
|
axis.title = element_text(face = "bold"),
|
|
axis.line = element_line(color = "black"),
|
|
panel.grid.major.y = element_line(color = "grey90", linetype = "dotted")
|
|
)
|
|
|
|
# Save plot
|
|
dir.create(output_dir, recursive = TRUE, showWarnings = FALSE)
|
|
ggsave(output_file, p, width = 11, height = 7, dpi = dpi_png)
|
|
|
|
message("✓ Mirror plot saved to: ", output_file)
|