rformassspectrometry / Spectra

Low level infrastructure to handle MS spectra
https://rformassspectrometry.github.io/Spectra/
34 stars 24 forks source link

filterPrecursorMzRange #256

Open cbroeckl opened 1 year ago

cbroeckl commented 1 year ago

DDA MS/MS defines the precursor that was used to trigger the MS/MS event, and defines the precursor mass as the trigger mass. However, every MS/MS event has a mass isolation window - i.e. a lower mz limit and upper limit. DIA defines a mass isolation window directly, and has no defined precursor. In each case, the precursor mass(es) are contained within the range specificed by the isolation window. DDA are also commonly 'contaminated' by precursor ions which were not the trigger precursor ion. In my mind, it therefore makes sense to think about DDA and DIA under the same umbrella. In doing so, we could piece together an MS/MS workflow (i think) which works for all forms of MS/MS.

i would like to propose a function similar to filterPrecursorMz, but turned around, so to speak. Rather than returning all the MS/MS spectra with defined precursor masses within a given mz range, return all MS/MS spectra for which a given precursor mass is within the isolation window mz range. Lets call this filterPrecursorMzRange (or something like that ;-) ). For HDMSe or other IMS-based precusor selections, we could also have a filterPrecursorDtRange (where Dt is drift time).

  1. XCMS performs feature detection on MS1 data
  2. Feature annotation (adduct, isotope, etc) via Camera/RamclustR/CliqueMS, whatever
  3. for all features of interest, lets just say all molecular ions, [M+H]+, [M+Na]+, etc.
    • find all MS/MS spectra which have sampled that precursor using filterPrecursorMzRange or filterPrecursorDtRange
    • determine precursor purity within the precursor range, as done in MSPurity (basically, precursor intensity divided by all MS1 signal intensity within defined MS1 mz range - would need to pull this from the raw mzML data, i think).
    • combine MS/MS spectra using one of the defined methods (or a new one) which also uses purity as a filter, or weight.

The purity filter would be able to remove MS/MS spectra (or de-weight them) to prevent MS/MS spectra from being assigned which are derived largely from 'contaminant' precursors. Once this filter is in place, one could also envision more complex combineSpectrum functions which utilize precursor and product ion intensity more quantitaively to keep (ideally) only genuine product ions for the given precursor.

This is a mental sketch - i don't have any Rcode mocked up. Wanted to float the concept and make sure it doesn't already exist before devoting time to it.

Thanks for all the development in this area!

jorainer commented 1 year ago

Hi Corey! Thanks for your input and thoughts!

Could be that we have already the functions in place that you suggested - but I got also confused and did not quite understand what the difference between the filterPrecursorMz and filterPrecursorMzRange you proposed is. Could you maybe clarify a bit?

As reference, what we have now in Spectra is the following:

cbroeckl commented 1 year ago

@jorainer it sounds like is exactly what i was looking for. I had a hunch you all had built it - you have been quite active!

Is there also a function built to determine precursor purity? https://www.bioconductor.org/packages/release/bioc/html/msPurity.html

It seems like it is literally 100*precursorIonIntensity/sum(AllMS1SignalIntensityWithinIsolationWindow). Not difficult to calculate, just potentially slow as you will have to go back to the raw mzML for each MS2 spectrum.