Skip to content
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

PrecursorIntensity of all MS2 spectra equal to zero? #6

Open
gmhhope opened this issue May 6, 2021 · 6 comments
Open

PrecursorIntensity of all MS2 spectra equal to zero? #6

gmhhope opened this issue May 6, 2021 · 6 comments

Comments

@gmhhope
Copy link

gmhhope commented May 6, 2021

Hi Johannes,

I noticed that in my dataset, all my precursor intensity of all MS2 spectra equal to zero? But I do get peaks when I look into the data. This is important for me as I need to filter the data with relatively high precursor intensity.

sps_ms2$precursorIntensity[1:30]
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

> unique(sps_ms2$precursorIntensity)
[1] 0

I can see TIC of the MS2 spectra:

> sps_ms2$totIonCurrent[1:20]
 [1] 10730646.00  6785630.50  4910262.00  2219103.75  2152170.00  5834306.00   258699.50  5996742.00  1365530.38
[10]  1163728.00   356782.12   300545.16  1608516.50    24769.94   678570.06   231850.31   429202.44   855109.00
[19]   405815.31   704396.00

Do you know why? Any ideas on the troubleshooting? I haven't tried it in your tutorial dataset. If I finish this run, I will try.

Hope you can help! Appreciate it!

Thanks,
Minghao Gong

@jorainer
Copy link
Owner

jorainer commented May 6, 2021

I know. Some instruments don't report the precursor intensity (we use Sciex and also have no precursor intensities). I have a utility function in xcms that calculates the precursor intensity of a MS2 spectrum based on the neighboring MS1 spectra data (i.e. using the data from the MS1 spectra measured before and after the MS2 spectrum - as far as I understood that's also how some vendor software determines the precursor intensity).

The function in xcms is called estimatePrecursorIntensity, but that function needs to be called on an OnDiskMSnExp object from the MSnbase package - so you would have to:

od <- MSnbase::readMSData(fls, mode = "onDisk")
pints <- xcms::estimatePrecursorIntensity(od, ppm = 10)

If you use fls in the same order than you have to read the data as a Spectra, all spectra should be in the correct order. You could test (assuming sps is the data that you read with sps <- Spectra(fls, MsBackenMzR())) that with:

all.equal(rtime(od), rtime(sps))

and if that's true, you could set the precursor intensities with

sps$precursorIntensity <- pints

That would be the workaround until I have that function also implemented in Spectra.

@gmhhope
Copy link
Author

gmhhope commented May 6, 2021

Hi Johannes,

FYI. When I loaded the XCMS together with Spectra libraries.
When I do:

cormat <- compareSpectra(sps_ms2filt_norm_l[[2]], ppm = 1)

It gives me this error:

Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘compareSpectra’ for signature ‘"Spectra", "missing"’

But then I think there is some conflicts in xcms. So this solves the issue:

cormat <- Spectra::compareSpectra(sps_ms2filt_norm_l[[2]], ppm = 1)

Maybe there is another function called compareSpectra in xcms?

Thanks,
Minghao

@gmhhope
Copy link
Author

gmhhope commented May 7, 2021

Thanks for the excellent workaround option. I have successfully implemented that! It cleared up the blockade.

BTW, I am not familiar with how to play around with the spectra object. is there a way I can sort the spectra object based on precursor Intensity? (e.g., I want to sort out the top 3 spectra out of a bunch of spectra that have overlapped precursorMz value).

Right now I am doing something not very elegant like this:

order_ind <- order(sps_ms2$precursorIntensity, decreasing = TRUE)
retained_ind <- sapply(order_ind, function(x)if(x<=3){TRUE}else{FALSE})
sps_select <- sps_ms2[retained_ind]

I think this works but I do want to have a better view of handling this type of object (S4)? Do you have a good cheatsheet or guideline for that?

Thanks a lot!

Best,
Minghao Gong

@jorainer
Copy link
Owner

jorainer commented May 7, 2021

for the problem you reported in the previous message: yes, I know, there is the problem that many functions with the same name are implemented in xcms/MSnbase and in Spectra. The way how you did it (by directly calling the implementation from the package you want, i.e. Spectra::compareSpectra is the correct way to fix that at present.

For the ordering - you can think of a Spectra object being a list and you can thus re-order the way you did (i.e. [index]). We don't have a cheatsheet yet, the best we can offer is the vignette in the Spectra package and this short tutorial.

Your problem is actually a quite interesting one. It would be difficult if you don't know the grouping of your spectra beforehand (i.e. if your sps_ms2 has all different precursor m/z values). If sps_ms2 is a set of spectra with ~ the same precursor m/z you could simply do:

top_3 <- sps_ms2[order(sps_ms2$precursorIntensity, decreasing = TRUE)][1:3]

otherwise you would need to first group them by similar m/z, then split it and do an lapply on the splitted list of Spectra calling the code above.

@gmhhope
Copy link
Author

gmhhope commented May 7, 2021

Thanks for your swift and detailed replies! That is extremely helpful!

My current way to run your Spectra package

Your problem is actually a quite interesting one. It would be difficult if you don't know the grouping of your spectra beforehand (i.e. if your sps_ms2 has all different precursor m/z values).

Currently, I am looping a list of sps_ms2 objects (they all have nearly the same precursor m/z) by using the filterPrecursorMz function. And then I select the top3 to match against massbank & hmdb. I don't think it is the optimal way to do it but right now I simply want to make it work in a recent project.

Some ideas (or wishlist) about the workflow.

I would like to share some ideas of my workflow which may be also relevant for many Spectrometry practitioners:

  1. Read the ms2 level spectra
  2. Then to avoid too much MS/MS searching, I may need to group them based on their properties to avoid matching all of them to the MS/MS database
  • filterPrecursorMz is used to go after the significant precursor m/z derived from MS1 analysis
  • Then I may need to figure out criteria to filter them by retention time (The current data is from DDA analyses which have an inclusion list that doesn't have retention time windows; so I ignore this as I don't have a good idea to do the RT filtering; But in future runs, I will have RT windows to filter them efficiently based on their MS1 run)
    • I think these ideas are aligned with MSexperiment, which you would like to have MS2 spectra directly associate with MS1 objects?!
  • I also think about doing clustering to select representative MS/MS spectra from a group of spectra isolated by filtering nearly the same precursorMz, as I think there may be MS/MS spectra of isomers in relatively closed RT windows. But given the complexity, I drop this option for now.
  1. After the grouping & filtering, I select three spectra with the highest precursor m/z Intensity from each group to match against database. Then I am thinking about the criteria to select a group of matches that are relatively reliable (maybe the > 0.7 will work).

  2. Finally, I would like to report the spectra, matching scores & possible compound IDs back to .json format, which we currently use for storing and visualizing in the server. At this moment, I need to rush so I am using a python package matchms to convert the .mgf format to .json.

Any suggestions will be welcome. I am mainly working through step 3 now. Thanks always for the supports! I hope the long session of idea-sharing is more helpful than annoying (just want to share, I felt talking through always help!)

Best regards,
Minghao Gong

@jorainer
Copy link
Owner

jorainer commented May 7, 2021

Thanks for the update. Note that the Spectra package is only supposed to provide the basic infrastructure to work with MS data - but we started also to define some more high level functionality that might simplify some of the tasks that you describe above in a new MetaboAnnotation R package (be aware that this package is in a very early stage)

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

No branches or pull requests

2 participants