Skip to content

Conversation

@Adafede
Copy link
Contributor

@Adafede Adafede commented Aug 14, 2025

ran updateCvParams.sh properly this time

@Adafede Adafede changed the title Update CVs Update CVs, add electronBeamEnergy Aug 14, 2025
@jorainer
Copy link
Collaborator

Quick question: was there already a "electronBeamEnergy" header variable before or did you add one? Seems you simply moved the header variable to a different position?

@Adafede
Copy link
Contributor Author

Adafede commented Aug 19, 2025

@jorainer It was already listed there, indeed, at the end and while adding in https://github.com/sneumann/mzR/pull/311/files#diff-463c44a6d90a9e18b0f360386960d386888894194c952be75b24d60196577ebbR27 for example, it felt more intuitive to place it next to the CID energy?

@jorainer
Copy link
Collaborator

ah, yes, of course. Makes more sense. I was just confused, because if you would have added a new header variable you would also need to increment the size of the vector/list - otherwise you run into a nullpointer.

Copy link
Collaborator

@jorainer jorainer left a comment

Choose a reason for hiding this comment

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

Please add also unit tests to check that the electroBeamEnergy header is set.

Also, I got a bit puzzled by the ms-obo version - seems you are replacing the existing one with an older version?

@Adafede
Copy link
Contributor Author

Adafede commented Aug 19, 2025

Please add also unit tests to check that the electroBeamEnergy header is set.

Happy to, but this would require an mzML with electroBeamEnergy in it? Shall I fake one/add it to msdata? Just need some guidance on how you would like this one at best and happy to implement it

@jorainer
Copy link
Collaborator

honestly - I would for now just check that the variable is returned - by the netCDF and the pwiz - and that the values are (presumably?) NA. If you happen to have your own mzML files with that electroBeamEnergy you could just report here that they are correctly extracted (maybe show the first x lines of the header() output).

@Adafede
Copy link
Contributor Author

Adafede commented Aug 19, 2025

Oh, yes, absolutely I can confirm that! I already converted thousands of files using my own branch and get the electronBeamEnergy 😄 maybe @Panzenboeck can also confirm?

(Mainly did it for Adafede/CentroidR#6)

@Adafede
Copy link
Contributor Author

Adafede commented Aug 19, 2025

Here a file with CID only:

<precursorList count="1">
            <precursor>
              <isolationWindow>
                <cvParam cvRef="MS" accession="MS:1000827" name="isolation window target m/z" value="100.075376300915" unitCvRef="MS" unitAccession="MS:1000040" unitName="m/z"/>
              </isolationWindow>
              <selectedIonList count="1">
                <selectedIon>
                  <cvParam cvRef="MS" accession="MS:1000744" name="selected ion m/z" value="100.075376300915" unitCvRef="MS" unitAccession="MS:1000040" unitName="m/z"/>
                  <cvParam cvRef="MS" accession="MS:1000041" name="charge state" value="1"/>
                </selectedIon>
              </selectedIonList>
              <activation>
                <cvParam cvRef="MS" accession="MS:1000422" name="beam-type collision-induced dissociation" value=""/>
                <cvParam cvRef="MS" accession="MS:1000045" name="collision energy" value="40.0" unitCvRef="UO" unitAccession="UO:0000266" unitName="electronvolt"/>
              </activation>
            </precursor>
          </precursorList>

and with EAD:

<precursorList count="1">
            <precursor>
              <isolationWindow>
                <cvParam cvRef="MS" accession="MS:1000827" name="isolation window target m/z" value="795.725926070743"/>
              </isolationWindow>
              <selectedIonList count="1">
                <selectedIon>
                  <cvParam cvRef="MS" accession="MS:1000744" name="selected ion m/z" value="795.725926070743" unitCvRef="MS" unitAccession="MS:1000040" unitName="m/z"/>
                  <cvParam cvRef="MS" accession="MS:1000042" name="peak intensity" value="0.0" unitCvRef="MS" unitAccession="MS:1000131" unitName="number of detector counts"/>
                  <cvParam cvRef="MS" accession="MS:1000041" name="charge state" value="1"/>
                </selectedIon>
              </selectedIonList>
              <activation>
                <cvParam cvRef="MS" accession="MS:1000133" name="collision-induced dissociation" value=""/>
                <cvParam cvRef="MS" accession="MS:1000045" name="collision energy" value="12.0" unitCvRef="UO" unitAccession="UO:0000266" unitName="electronvolt"/>
                <cvParam cvRef="MS" accession="MS:1003294" name="electron activated dissociation" value=""/>
                <cvParam cvRef="MS" accession="MS:1003410" name="electron beam energy" value="16.0" unitCvRef="UO" unitAccession="UO:0000266" unitName="electronvolt"/>
              </activation>
            </precursor>
          </precursorList>

(with still a small CID current for transmission)

@Panzenboeck
Copy link

@Adafede, yes, I can confirm that I also get the electronBeamEnergy and I highly recommend CentroidR!

@jorainer
Copy link
Collaborator

Thanks for the update @Adafede - for the two example files that you show above, can you maybe show what mzR::header() returns for these?

@Adafede
Copy link
Contributor Author

Adafede commented Aug 20, 2025

Sure!

library(mzR)
#> Loading required package: Rcpp
path_cid <- "Downloads/20230912_nexus_plate_1_Q1_pos_A1_CID_20ev.mzML"
path_ead <- "Downloads/20230912_nexus_plate_1_Q1_pos_A1_EAD_16KE.mzML"
path_cid_mini <- "Downloads/mini_cid.mzmL"
path_ead_mini <- "Downloads/mini_ead.mzmL"

range <- 1L:5L

## Switch to the mini solution if no access to the large original file
if (!path_cid |>
  file.exists()) {
  print("using mini example")
  path_cid <- path_cid_mini
}
if (!path_ead |>
  file.exists()) {
  print("using mini example")
  path_ead <- path_ead_mini
}

in_file_cid <- path_cid |>
  mzR::openMSfile(backend = "pwiz")
in_file_ead <- path_ead |>
  mzR::openMSfile(backend = "pwiz")

hdr_cid <- in_file_cid |>
  mzR::header()
hdr_ead <- in_file_ead |>
  mzR::header()

pks_cid <- in_file_cid |>
  mzR::peaks()
pks_ead <- in_file_ead |>
  mzR::peaks()

in_file_cid |>
  mzR::close()
in_file_ead |>
  mzR::close()

hdr_cid_mini <- hdr_cid[!hdr_cid$collisionEnergy |> is.na(), ][range, ]
hdr_cid_mini$seqNum <- range
hdr_ead_mini <- hdr_ead[!hdr_ead$collisionEnergy |> is.na(), ][range, ]
hdr_ead_mini$seqNum <- range

pks_cid_mini <- pks_cid[!hdr_cid$collisionEnergy |> is.na()][range]
pks_ead_mini <- pks_ead[!hdr_ead$collisionEnergy |> is.na()][range]

print(hdr_cid_mini)
#>    seqNum acquisitionNum msLevel polarity peaksCount totIonCurrent
#> 21      1             21       2        1        872     58107.316
#> 22      2             22       2        1       1361     25404.693
#> 24      3             24       2        1       1158     34536.109
#> 25      4             25       2        1        256      4207.717
#> 27      5             27       2        1        919     11382.867
#>    retentionTime basePeakMZ basePeakIntensity collisionEnergy
#> 21         2.075          0                 0              20
#> 22         2.133          0                 0              20
#> 24         2.307          0                 0              20
#> 25         2.364          0                 0              20
#> 27         2.539          0                 0              20
#>    electronBeamEnergy ionisationEnergy lowMZ highMZ precursorScanNum
#> 21                 NA                0     0      0               NA
#> 22                 NA                0     0      0               NA
#> 24                 NA                0     0      0               NA
#> 25                 NA                0     0      0               NA
#> 27                 NA                0     0      0               NA
#>    precursorMZ precursorCharge precursorIntensity mergedScan
#> 21    107.0464               0                  0         NA
#> 22    155.0720               0                  0         NA
#> 24    132.9587               0                  0         NA
#> 25    608.7878               0                  0         NA
#> 27    131.1037               0                  0         NA
#>    mergedResultScanNum mergedResultStartScanNum mergedResultEndScanNum
#> 21                  NA                       NA                     NA
#> 22                  NA                       NA                     NA
#> 24                  NA                       NA                     NA
#> 25                  NA                       NA                     NA
#> 27                  NA                       NA                     NA
#>    injectionTime filterString                              spectrumId
#> 21             0         <NA> sample=1 period=1 cycle=20 experiment=2
#> 22             0         <NA> sample=1 period=1 cycle=20 experiment=3
#> 24             0         <NA> sample=1 period=1 cycle=21 experiment=2
#> 25             0         <NA> sample=1 period=1 cycle=21 experiment=3
#> 27             0         <NA> sample=1 period=1 cycle=22 experiment=2
#>    centroided ionMobilityDriftTime isolationWindowTargetMZ
#> 21      FALSE                   NA                107.0464
#> 22      FALSE                   NA                155.0720
#> 24      FALSE                   NA                132.9587
#> 25      FALSE                   NA                608.7878
#> 27      FALSE                   NA                131.1037
#>    isolationWindowLowerOffset isolationWindowUpperOffset scanWindowLowerLimit
#> 21                         NA                         NA                   50
#> 22                         NA                         NA                   50
#> 24                         NA                         NA                   50
#> 25                         NA                         NA                   50
#> 27                         NA                         NA                   50
#>    scanWindowUpperLimit
#> 21                 1500
#> 22                 1500
#> 24                 1500
#> 25                 1500
#> 27                 1500
print(hdr_ead_mini)
#>    seqNum acquisitionNum msLevel polarity peaksCount totIonCurrent
#> 21      1             21       2        1       1480      22693.71
#> 22      2             22       2        1       1266      16772.92
#> 24      3             24       2        1       1332      20061.95
#> 25      4             25       2        1        961      10115.71
#> 27      5             27       2        1       1266      16157.14
#>    retentionTime basePeakMZ basePeakIntensity collisionEnergy
#> 21         2.096          0                 0              12
#> 22         2.184          0                 0              12
#> 24         2.388          0                 0              12
#> 25         2.476          0                 0              12
#> 27         2.679          0                 0              12
#>    electronBeamEnergy ionisationEnergy lowMZ highMZ precursorScanNum
#> 21                 16                0     0      0               NA
#> 22                 16                0     0      0               NA
#> 24                 16                0     0      0               NA
#> 25                 16                0     0      0               NA
#> 27                 16                0     0      0               NA
#>    precursorMZ precursorCharge precursorIntensity mergedScan
#> 21    250.9533               0                  0         NA
#> 22    483.1817               1                  0         NA
#> 24    155.1042               0                  0         NA
#> 25    398.3646               0                  0         NA
#> 27    152.9503               0                  0         NA
#>    mergedResultScanNum mergedResultStartScanNum mergedResultEndScanNum
#> 21                  NA                       NA                     NA
#> 22                  NA                       NA                     NA
#> 24                  NA                       NA                     NA
#> 25                  NA                       NA                     NA
#> 27                  NA                       NA                     NA
#>    injectionTime filterString                              spectrumId
#> 21             0         <NA> sample=1 period=1 cycle=20 experiment=2
#> 22             0         <NA> sample=1 period=1 cycle=20 experiment=3
#> 24             0         <NA> sample=1 period=1 cycle=21 experiment=2
#> 25             0         <NA> sample=1 period=1 cycle=21 experiment=3
#> 27             0         <NA> sample=1 period=1 cycle=22 experiment=2
#>    centroided ionMobilityDriftTime isolationWindowTargetMZ
#> 21      FALSE                   NA                250.9533
#> 22      FALSE                   NA                483.1817
#> 24      FALSE                   NA                155.1042
#> 25      FALSE                   NA                398.3646
#> 27      FALSE                   NA                152.9503
#>    isolationWindowLowerOffset isolationWindowUpperOffset scanWindowLowerLimit
#> 21                         NA                         NA                   50
#> 22                         NA                         NA                   50
#> 24                         NA                         NA                   50
#> 25                         NA                         NA                   50
#> 27                         NA                         NA                   50
#>    scanWindowUpperLimit
#> 21                 1500
#> 22                 1500
#> 24                 1500
#> 25                 1500
#> 27                 1500

mzR::writeMSData(file = path_cid_mini, header = hdr_cid_mini, object = pks_cid_mini)
mzR::writeMSData(file = path_ead_mini, header = hdr_ead_mini, object = pks_ead_mini)

Created on 2025-08-20 with reprex v2.1.1

With the mini examples in case here below
mini_examples.zip

@jorainer jorainer requested review from jorainer and sneumann August 20, 2025 08:26
Copy link
Collaborator

@jorainer jorainer left a comment

Choose a reason for hiding this comment

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

Thanks @Adafede for adding support for this spectra variable! I'm OK with the C++ and R code - for the OBO and CV terms I would like to have @sneumann a look (as well as to merge as he's the maintainer).

Copy link
Owner

@sneumann sneumann left a comment

Choose a reason for hiding this comment

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

Looks good to me. For the psi-ms I created a shell-script many years back to perform the update, and Adriano now has confirmed that it still works :-) Also, the perceived downgrade of psi-ms.obo makes sense.
Yours, Steffen

@sneumann
Copy link
Owner

What is missing is the contributor in the DESCRIPTION file...

@Adafede
Copy link
Contributor Author

Adafede commented Aug 20, 2025

So...after some additional checks...

Happy to hear your thoughts @jorainer

@jorainer
Copy link
Collaborator

as far as I understand you are skipping to WRITE missing/NaN values back to the mzML file - which makes total sense to me! I would keep it like that - but then update/fix the unit tests for that.

why the unit tests fail but are still green is a very odd... maybe related to RUnit instead of testthat... no clue.

@jorainer
Copy link
Collaborator

jorainer commented Sep 2, 2025

We are now getting bunch of errors in Spectra and MSnbase - because the export() does not work - the header validator in mzR cries that no electronBeamEnergy is available in the submitted header. I would maybe like to change the electronBeamEnergy to be an optional, but not required field? Is that OK @Adafede ?

@Adafede
Copy link
Contributor Author

Adafede commented Sep 2, 2025

@jorainer Absolutely! Please let me know when done so that I can remove my ugly temporary fix in https://github.com/Adafede/CentroidR/blob/main/R/centroid_one_file.R#L335-L350 😊

(I believe all of these could be optional)

@jorainer
Copy link
Collaborator

jorainer commented Sep 3, 2025

Update: @sneumann , we fixed now the failing unit tests (see results from unit tests here) and importantly also fixed an issue that causes both the MSnbase and Spectra packages to fail with the current mzR: we made the electronBeamEnergy an optional header column for the export functionality.

@sneumann sneumann merged commit 15fde15 into sneumann:devel Sep 3, 2025
3 checks passed
@sneumann
Copy link
Owner

sneumann commented Sep 3, 2025

Thanks, merged and pushed to BioC. Yours, Steffen

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.

4 participants