Skip to content

MassQL Introduction

About Mass Spec Query Language

The Mass Spec Query Langauge (MassQL) is a domain specific language meant to be a succinct way to express a query in a mass spectrometry centric fashion. It is inspired by SQL, but it attempts to bake in assumptions of mass spectrometry to make querying much more natural for mass spectrometry users. Broadly we attempt to design it according to several principles:

  1. Expressiveness - Capture complex mass spectrometry patterns that the community would like to look for
  2. Precision - Exactly prescribe how to find data without ambiguity
  3. Relatively Natural - MassQL should be relatively easy to read and write and even use as a way to communicate ideas about mass spectrometry, you know like a language.

Why does Mass Spec Query Language Exist?

The intrinsic physical and chemical property of molecules when analyzed by mass spectrometry imprint patterns upon mass spectrometry data. This affords the opportunity to formulate queries to find these patterns in raw mass spectrometry data. However, within the computational mass spectrometry ecosystem, the lack of a ergonomic, flexible, and scalable approach to express these patterns prevents the community from taking full advantage of expert knowledge of these patterns to thoroughly and quickly mine mass spectrometry data for new molecules. Therefore, I created the Mass Spectrometry Query Language (MassQL) to empower mass spectrometrists and chemists to write their own queries in a flexible, precise, and scalable fashion.


Mingxun Wang is the creator and main developer of MassQL. Please contact me if you have questions! I'm hoping this becomes a community effort so reach out if you want to help/use MassQL.

Definition of a Query

There are several parts

<Type of Data>

Type of Data

This determines the type of data you want to get. At its most fundamental level, its the peaks for either

  1. MS1DATA
  2. MS2DATA

Further, there are functions that can modify this data

  1. scaninfo - This provides likely the most information you'd want for each scan
  2. scansum - Summation of the scan (TIC)
  3. scannum - Returns the scan number
  4. scanmaxint - Returns the max intensity per spectrum (BPI)

Experimental Functions

  1. scanrangesum
  2. scanmaxmz
  3. scanrun


These are conditions to filter for scans of interest (by looking for peaks and sets of peaks) within the mass spectrometry data. You can create clauses, which are specific conditions and the associated qualifiers. You may further combine multiple conditions with AND. AND will indicate that within a specific spectrum, all the conditions must be met.


The syntax for this is <condition>=<value>, e.g. MS2PROD=144.1.

The types of conditions are as follows


Setting the minimum retention time in minutes


Setting the maximum retention time in minutes


Setting the minimum scan number (this is inclusive)


Setting the maximum scan number (this is inclusive)


Finding MS2 spectra with a given charge if reported by the instrument


The polarity that will be chosen. (Positive, Negative)


Looking for an MS2 peak


Looking for an MS2 precursor m/z


Looking for MS1 peak m/z


We have a special keyword to interact with mobility data. Specifically, the syntax enables you to set min and max bounds for the mobility

MOBILITY=range(min=1, max=2)

The units here are whatever your mass spectrometer reports and are not converted to collision cross section (CCS).

Fun with m/z variables and Mobility

You can even create polygons within the m/z mobility space to get data. Here is a quick example

QUERY scaninfo(MS2DATA) WHERE MS2PREC=X AND MOBILITY=range(min=X*0.0011+0.5-0.1, max=X*0.0011+0.5+0.1)
This represents approximately this parallelogram region.


Looking for a neutral loss from precursor m/z in the MS2 spectrum. For example, if a molecule has a precursor m/z of 500, and you are searching for an MS2NL of 16, it will look for a peak appearing at 500 - 16 = 484 m/z.


These can be attached to conditions to modify some properties about the peaks we are looking for.

Mass Accuracy

These two fields enable setting a peak m/z tolerance


Default Values

The default tolerance when no qualifier is provided is 0.1 Da.

Intensity Relative to Full Spectrum

These two fields enable to set an minimum intensity


INTENSITYVALUE - This indicates a minimum intensity value in terms of arbitrary units. INTENSITYPERCENT - This indicates a minimum percent of maximum peak in the spectrum. INTENSITYTICPERCENT - This indicates a minimum percent of total TIC in the spectra.

Default Values

The default minimum intensity value is 0, so it will accept any peak. This is generally not what you want, so likely you do want to set this.

Intensity Relative to Other Peaks

Here we can start imposing relative intensities between peaks


Intensity Matching Between Peaks

This is actually complicated, but you'll end up with one peak per variable that is the reference and all others are relative to that reference.

MS1MZ=X:INTENSITYMATCH=Y:INTENSITYMATCHREFERENCE # This is the reference peak which all other peaks' intensities will be compared to
MS1MZ=X+2:INTENSITYMATCH=Y*2:INTENSITYMATCHPERCENT=1 # The Y*2 denotes that it must be 2 times the intensity of the first peak

Values of Conditions, Qualifiers

As mentioned above, the value of certain conditions can be numbers (more precisely floats). However, its sometimes in convenient to have to actually calculate out the m/z for an MS2PROD condition and also the derivation is obfuscated if its just a single number. You can simply list it out as a numerical expression


and this will get calculated to mean


You can even do more advanced things that are native to chemistry/biochemistry without having to look up numbers, and they are listed below.

MS2MZ and MS2PROD synonyms

MS2MZ and MS2PROD mean the same thing in the language.

ANY keyword

If you do not have a specific requirement of a peak m/z, you can use the ANY keyword.

For example:

MS2PROD=ANY:MASSDEFECT=massdefect(min=0.1, max=0.2)


In cases where you do not know the mass of the peaks for a specific pattern, but you know the pattern of peaks relative to each other, e.g. isotopic patterns, you can use the variable X in place. For example:


Limiting Range of X

If you want to limit the range you can set another condition, X=range(min=100, max=500)

Limiting Mass Defect of X

If you want to set limits on the decimal part of X, you can set another condition, X=massdefect(min=0.1, max=0.5)

Molecular Formula

To save us all a little bit of time convert lookup of formulas into masses, you can use the syntax:


to easily calcualte the mono isotopic mass of H2O. It will substitute as


Advanced Usage

If you want to make functions out of formula masses, you totally can, like below

MS2PROD=100 + formula(CH2)*2

Amino Acid Masses

To calculate amino acid masses, you can use the following syntax

MS2PROD=100 + aminoaciddelta(G)

which will calculate out to


Multiple Amino Acids

If you want to use multiple amino acids, no problem:


Peptide Masses

If you're in the proteomics camp, you can automatically calculate peptide fragementation.

MS2PROD=peptide(G, charge=1, ion=y)

will yield



Filters are like conditional but we don't elimate scans based on the condition. Rather, we simply filter out peaks within the spectra.

This is useful for things like SRM or SIM/XIC.


OR operations

If you are looking for two peaks but either of them could be present, you can use the following syntax

MS2PROD=(100 OR 104)

You can use with variables as well.

MassQL Patterns

If you're interested in doing some more advanced queries in MassQL, we have a dedicated patterns page to show you ways we've approached some interesting applications. By no means is it comprehensive, but we hope it helps. Check it out here.


XIC Generation

MS1 XIC, m/z = 100


MS2 With Sugar Loss - Neutral Loss Scan

Neutral Loss, 163 Da


Brominated Compounds


MS2 with distinct fragment(s) - Precursor Ion Scan

One Product Ion, m/z = 660.2


Two Product Ions, m/z = 660.2 and 468.2


How To Use MassQL

Python API

We have a python API that you can utilize in your own software. Checkout the package here on PyPi.


We have an R implementation by the community, check it out here.

Commandline Utility

We have a standalone script that can execute queries on spectrum files that can be installed by the package PyPi.

Nextflow Workflow

We have a nextflow workflow to enable scalable queries across hundreds of thousands of mass spectrometry files.

ProteoSAFe Workflow

We have a proteosafe workflow that we have created that nicely integrates into GNPS - Try the beta here.

See more details here.

Workflow Details

There are several options that you probably will care about

  1. Extracting found MS scans as part of output, default this is off, if you want to do downstream molecular networking - turn this on
  2. If you want to run multiple queries together, you can now, just separate your queries with ||| and then results from multiple queries will be merged together

GNPS Repository Scale Queries

One of the powerful things with MassQL is the ability to scale up to huge amounts of data. Luckily at GNPS we have tons of data. You can use the above workflow to select datasets (or your own), with hundreds of files queriable at once. However, sometimes you want to go really big and search everything at once. We have these tools available but they currently require a large amount of compute and require special permissions. If you want to do repository scale queries, please contact Ming to collaborate on it.


You can checkout how to use MassQL In PyOpenMS here.


We have built out a web API for people to use, especially for parsing.

Simply put in the query as a url encoded parameter and a JSON representation of the parse is returned.

Interactive Web Sandbox

Checkout the interactive sandbox here.

Debugging Your Query

I would recommend you check out the interactive sandbox listed above. One of the features here is we try to translate your MassQL query into a visualization and into English. Generally issues with queries run into problems with of misunderstanding what each condition and qualifier mean or setting your requirements a bit too strict. Both the visualization and translation to English helps with that.

Last update: May 24, 2022 15:50:28