rformassspectrometry / Spectra

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

Concatenate Spectra #220

Closed MonicaCalSan closed 2 years ago

MonicaCalSan commented 2 years ago

I'm trying to make a new Spectra object joining two previous ones, but I get an error message that I don't understand.

if (exists("FinalDB")==FALSE){FinalDB<-applyProcessing(PreDB)} else {
FinalDB<-c(applyProcessing(PreDB),FinalDB)}}

I'm using it in a loop, so that PreDB is generated a few times, and all these PreDB are together in FinalDB. Is that possible? Or I'm trying to do something crazy? Here is the error that I get:

Error: BiocParallel errors
  1 remote errors, element index: 1
  0 unevaluated and other errors
  first remote error: argumento no-numérico para operador binario
In addition: Warning message:
In serialize(data, node$con) :
  'package:stats' may not be available when loading
jorainer commented 2 years ago

What you're doing should be correct - it is possible to combine Spectra using c(spectra1, spectra2) - and what is also correct is to use the applyProcessing to make sure any potential data processing steps are applied. The problem now is that I don't understand where this error message comes from - from the c call or from the applyProcessing.

Could you please use register(SerialParam()) before your for loop to ensure to disable parallel processing (error messages from parallel processing are sometimes a little confusing) and try again?

MonicaCalSan commented 2 years ago

Now the last part of the error have disappeared, but I still get the message. I have realized that the error could be related to the previous step that I'm doing. I'm filtering mz values in the Spectra that I want to combine, and after filtering I can't ask for mz values to be shown, since I get an error. Before the filter:

PrepreDB[1]$mz
NumericList of length 1
[[1]] 61.9880959124361 89.0244821921824 90.0279388341876 ... 982.989209750451 1025.34145789371 1026.34240282505

I run the filter: PreDB<-filterMzValues(PrepreDB,mz=Tofilterlist$mzfragments[i],ppm=20,keep=FALSE) And then, if I ask for mz values I get the error:

PreDB[1]$mz
Error: BiocParallel errors
  1 remote errors, element index: 1
  0 unevaluated and other errors
  first remote error: non-numeric argument to binary operator
sgibb commented 2 years ago

Are all elements in Tofilterlist$mzfragments[i] numeric values (for all possible i) or are there some null-length vectors?

MonicaCalSan commented 2 years ago

It is a list of elements:

Tofilterlist$mzfragments[1]
[[1]]
 [1]  73.5903 144.4252 242.0540 301.0416 301.0696 302.0697 302.8985 352.1908 426.0949 609.1810

Is here the problem?

MonicaCalSan commented 2 years ago

I have modified the code, now it is not giving error and I can get PreDB$mz[1] perfectly, by using unlist: PreDB<-filterMzValues(PrepreDB,mz=unlist(Tofilterlist$mzfragments[i]),ppm=20,keep=FALSE) However, when trying to concatenate, I still get an error:

if (exists("FinalNewIDDB")==FALSE){FinalNewIDDB<-applyProcessing(NewIDDB)} else {
  FinalNewIDDB<-c(applyProcessing(NewIDDB),FinalNewIDDB)}}
Error in .concatenate_spectra(unname(list(unname(x), ...))) : 
  Can not concatenate 'Spectra' objects with non-empty processing queue. Consider calling 'applyProcessing' before.

I'm attaching the whole code, because I don't know where to applyProcessing:

for (i in 1:nlist){
PrepreDB<-filterRt(applyProcessing(FINALDB),rt=c(as.numeric(Tofilterlist$rt[i])-1,as.numeric(Tofilterlist$rt[i])+1),msLevel=2)
applyProcessing(PrepreDB)
PreDB<-filterMzValues(PrepreDB,mz=unlist(Tofilterlist$mzfragments[i]),ppm=20,keep=FALSE)
if (exists("FinalNewIDDB")==FALSE){FinalNewIDDB<-applyProcessing(NewIDDB)} else {
FinalNewIDDB<-c(applyProcessing(NewIDDB),FinalNewIDDB)}}
jorainer commented 2 years ago

It is enough to call the applyProcessing just before you concatenate the Spectra. Note that in your code above you are concatenating a NewIDDB, but are filtering a PreDb?

Maybe a slight modification of the code could make it easier?

sps_list <- vector("list", nlist)
for (i in seq_len(nlist)) {
  res <- filterRt(FINALDB, rt = c(1, -1) + as.numeric(Tofilterlist$rt[i]), msLevel = 2)
  res <- filterMzValues(res, mz = unlist(Tofilterlist$mzfragments[i]), ppm = 20, keep = FALSE)
  sps_list[[i]] <- res
}
sps_list <- lapply(sps_list, applyProcessing)
FinalNewIDDB <- concatenateSpectra(sps_list)

Alternatively, you could use FinalNewIDDB <- do.call(c, sps_list).

MonicaCalSan commented 2 years ago

Thanks so much! It seems it works now!