corems
Table of Contents
- Introduction
- Installation
- Execution
- Sibling Projects
CoreMS
CoreMS is a comprehensive mass spectrometry framework for software development and data analysis of small molecules analysis.
Data handling and software development for modern mass spectrometry (MS) is an interdisciplinary endeavor requiring skills in computational science and a deep understanding of MS. To enable scientific software development to keep pace with fast improvements in MS technology, we have developed a Python software framework named CoreMS. The goal of the framework is to provide a fundamental, high-level basis for working with all mass spectrometry data types, allowing custom workflows for data signal processing, annotation, and curation. The data structures were designed with an intuitive, mass spectrometric hierarchical structure, thus allowing organized and easy access to the data and calculations. Moreover, CoreMS supports direct access for almost all vendors’ data formats, allowing for the centralization and automation of all data processing workflows from the raw signal to data annotation and curation.
CoreMS aims to provide
- logical mass spectrometric data structure
- self-containing data and metadata storage
- modern molecular formulae assignment algorithms
- dynamic molecular search space database search and generator
Current Version
4.1.0
Main Developers/Contact
Documentation
- Docs site (pdoc): corems.html — package landing page includes the README and the full installation guide
- Installation source: docs/user/installation.md (also rendered into the pdoc landing page via
corems.__doc__) - Overview slides: CoreMS-Overview.pdf
Build local docs: just docu, then open docs/corems.html.
Contributing
As an open source project, CoreMS welcomes contributions of all forms. See the contributing guide for external (GitHub) and internal (GitLab) workflows. Maintainers: see the release guide.
Branches: master is the stable release line (PyPI and tags). dev is the integration branch for ongoing work. Open PRs and MRs against dev only; maintainers merge dev into master when cutting a release.
Data formats
Data input formats
- Bruker Solarix (CompassXtract)
- Bruker Solarix transients, ser and fid (FT magnitude mode only)
- ThermoFisher (.raw)
- Spectroswiss signal booster data-acquisition station (.hdf5)
- MagLab ICR data-acquisition station (FT and magnitude mode) (.dat)
- ANDI NetCDF for GC-MS (.cdf)
- mzml for LC-MS (.mzml)
- Generic mass list in profile and centroid mde (include all delimiters types and Excel formats)
- CoreMS exported processed mass list files(excel, .csv, .txt, pandas dataframe as .pkl)
- CoreMS self-containing Hierarchical Data Format (.hdf5)
- Pandas Dataframe
- Support for cloud Storage using s3path.S3path
Data output formats
- Pandas data frame (can be saved using pickle, h5, etc)
- Text Files (.csv, tab separated .txt, etc)
- Microsoft Excel (xlsx)
- Apache Parquet (.parquet)
- Automatic JSON for metadata storage and reuse
- Self-containing Hierarchical Data Format (.hdf5) including raw data and time-series data-point for processed data-sets with all associated metadata stored as json attributes
Data structure types
- LC-MS
- GC-MS
- Transient
- Mass Spectra
- Mass Spectrum
- Mass Spectral Peak
- Molecular Formula
Available features
FT-MS Signal Processing, Calibration, and Molecular Formula Search and Assignment
- Apodization, Zerofilling, and Magnitude mode FT
- Manual and automatic noise threshold calculation
- Peak picking using apex quadratic fitting
- Experimental resolving power calculation
- Frequency and m/z domain calibration functions:
- LedFord equation
- Linear equation
- Quadratic equation
- Automatic search most abundant Ox homologue series
- Automatic local (SQLite) or external (PostgreSQL) database check, generation, and search
- Automatic molecular formulae assignments algorithm for ESI(-) MS for natural organic matter analysis
- Automatic fine isotopic structure calculation and search for all isotopes
- Flexible Kendrick normalization base
- Kendrick filter using density-based clustering
- Kendrick classification
- Heteroatoms classification and visualization
GC-MS Signal Processing, Calibration, and Compound Identification
- Baseline detection, subtraction, smoothing
- m/z based Chromatogram Peak Deconvolution,
- Manual and automatic noise threshold calculation
- First and second derivatives peak picking methods
- Peak Area Calculation
- Retention Index Calibration
- Automatic local (SQLite) or external (MongoDB or PostgreSQL) database check, generation, and search
- Automatic molecular match algorithm with all spectral similarity methods
High Resolution Mass Spectrum Simulations
- Peak shape (Lorentz, Gaussian, Voigt, and pseudo-Voigt)
- Peak fitting for peak shape definition
- Peak position in function of data points, signal to noise and resolving power (Lorentz and Gaussian)
- Prediction of mass error distribution
- Calculated ICR Resolving Power based on magnetic field (B), and transient time(T)
LC-MS Signal Processing, Molecular Formula Search and Assignment, and Spectral Similarity Searches
See walkthrough in this notebook
- Two dimensional (m/z and retention time) peak picking using persistent homology
- Smoothing, cetroid detection, and integration of extracted ion chromatograms
- Peak shape metric calculations including half peak height, tailing factor, and dispersity index
- MS1 deconvolution of mass features
- Idenfitication of 13C isotopes within the mass features
- Compatibility with molecular formula searching on MS1 or MS2 spectra
- Spectral search capability using entropy similarity
Installation
python -m venv venv && source venv/bin/activate # Windows: venv\Scripts\activate
pip install -U pip
pip install corems
python -c "import corems; print(corems.__version__)"
CoreMS 4.0+ requires Python 3.11+ (including 3.14). Dependencies (including pythonnet) come from pyproject.toml with the package.
pip install "corems[dev]" # tests / docs tooling
Full guide (venv, extras, SQLite vs PostgreSQL, Thermo .raw / .NET 8, troubleshooting):
→ docs/user/installation.md (source)
→ On the docs site: Installing CoreMS (same page as the API landing docs)
Thermo RAW needs a host .NET 8 runtime and PYTHONNET_RUNTIME=coreclr (details in the install guide). The CoreMS Docker image already includes .NET 8; see Docker image.
Building and Running the CoreMS Docker Image
CoreMS provides a Dockerfile that packages the entire application (including .NET 8 runtime for Thermo .raw file support) into a self-contained image. This is useful for running CoreMS in a reproducible environment without installing dependencies on your host system.
Prerequisites
- Docker installed and running on your system.
- The CoreMS repository cloned locally.
- Navigate to the root of the CoreMS repository before running any commands.
Building the Docker Image
The justfile provides convenience recipes for building the image (install just first — see https://just.systems). The image is tagged with the current version from .bumpversion.cfg.
On Linux/Windows (standard build):
just build-image-local
On macOS (cross-platform build for linux/amd64):
just build-image-mac-local
This runs docker build with the --platform linux/amd64 flag, which is necessary when building on Apple Silicon (M1/M2/M3) Macs to ensure compatibility.
Alternatively, you can build manually with:
docker build -t corems:<version> .
Replace <version> with your desired tag (e.g., 4.1.0).
What the Dockerfile Does
The Dockerfile performs the following steps:
- Starts from a
python:3.13-slimbase image. - Installs the .NET 8 runtime (required for Thermo .raw file support via PythonNET).
- Copies the CoreMS source code into the image.
- Installs CoreMS and all its dependencies via
pip install .. - Installs
pytest-xdistandpytest-covfor running tests. - Removes build-time dependencies (gcc, python3-dev) to keep the image lean.
Running the Docker Image
On Linux/Windows:
just image-run-local
On macOS:
just image-run-mac-local
This launches an interactive bash shell inside the container:
docker run -it corems:<version>
From within the container, you can import and use CoreMS directly:
python3 -c "import corems; print(corems.__version__)"
Mounting Data into the Container
To process your own data files, mount a local directory into the container:
docker run -it -v /path/to/your/data:/data corilo/corems:<version>
Your files will then be accessible at /data inside the container.
Managing the PostgreSQL Database with Docker Compose
The docker-compose.yml file defines a PostgreSQL database service for CoreMS. The justfile provides recipes to manage it:
Start the database:
just db-up
Stop the database:
just db-down
View database logs:
just db-logs
These are equivalent to running docker-compose up -d, docker-compose down, and docker-compose logs -f respectively.
Example for FT-ICR Data Processing
More examples can be found in the examples/notebooks directory
- Basic functionality example
from corems.transient.input.brukerSolarix import ReadBrukerSolarix
from corems.molecular_id.search.molecularFormulaSearch import SearchMolecularFormulas
from corems.mass_spectrum.output.export import HighResMassSpecExport
from matplotlib import pyplot
file_path= 'tests/tests_data/ftms/srfa_bruker_solarix_direct_infusion/ESI_NEG_SRFA.d'
# Instatiate the Bruker Solarix reader with the filepath
bruker_reader = ReadBrukerSolarix(file_path)
# Use the reader to instatiate a transient object
bruker_transient_obj = bruker_reader.get_transient()
# Calculate the transient duration time
T = bruker_transient_obj.transient_time
# Use the transient object to instatitate a mass spectrum object
mass_spectrum_obj = bruker_transient_obj.get_mass_spectrum(plot_result=False, auto_process=True)
# The following SearchMolecularFormulas function does the following
# - searches monoisotopic molecular formulas for all mass spectral peaks
# - calculates fine isotopic structure based on monoisotopic molecular formulas found and current dynamic range
# - searches molecular formulas of correspondent calculated isotopologues
# - settings are stored at SearchConfig.json and can be changed directly on the file or inside the framework class
SearchMolecularFormulas(mass_spectrum_obj, first_hit=False).run_worker_mass_spectrum()
# Iterate over mass spectral peaks objs within the mass_spectrum_obj
for mspeak in mass_spectrum_obj.sort_by_abundance():
# If there is at least one molecular formula associated, mspeak returns True
if mspeak:
# Get the molecular formula with the highest mass accuracy
molecular_formula = mspeak.molecular_formula_lowest_error
# Plot mz and peak height
pyplot.plot(mspeak.mz_exp, mspeak.abundance, 'o', c='g')
# Iterate over all molecular formulas associated with the ms peaks obj
for molecular_formula in mspeak:
# Check if the molecular formula is a isotopologue
if molecular_formula.is_isotopologue:
# Access the molecular formula text representation and print
print (molecular_formula.string)
# Get 13C atoms count
print (molecular_formula['13C'])
else:
# Get mz and peak height
print(mspeak.mz_exp,mspeak.abundance)
# Save data
## to a csv file
mass_spectrum_obj.to_csv("filename")
mass_spectrum_obj.to_hdf("filename")
# to pandas Datarame pickle
mass_spectrum_obj.to_pandas("filename")
# to parquet
mass_spectrum_obj.to_parquet("filename")
# Extract data as a pandas Dataframe
df = mass_spectrum_obj.to_dataframe()
UML Diagrams
Class diagrams for the main data-model stacks live in docs/uml:
- Direct Infusion FT-MS (
Direct_Infusion_FTMS_Data_Model.svg) - GC-MS (
GC_MS_Data_Model.svg) - LC-MS (
LC_MS_Data_Model.svg)
Citing CoreMS
If you use CoreMS in your work, please cite the archived release on Zenodo. The badge below is the concept DOI — it always resolves to the latest archived release, and each archived release also has its own version-specific DOI listed on that page.
For citation metadata (BibTeX, RIS, etc.), use the "Cite this repository" button on the GitHub sidebar, click "Export" on the Zenodo page above, or see CITATION.cff in the repository root.
This material was prepared as an account of work sponsored by an agency of the United States Government. Neither the United States Government nor the United States Department of Energy, nor Battelle, nor any of their employees, nor any jurisdiction or organization that has cooperated in the development of these materials, makes any warranty, express or implied, or assumes any legal liability or responsibility for the accuracy, completeness, or usefulness or any information, apparatus, product, software, or process disclosed, or represents that its use would not infringe privately owned rights.
Reference herein to any specific commercial product, process, or service by trade name, trademark, manufacturer, or otherwise does not necessarily constitute or imply its endorsement, recommendation, or favoring by the United States Government or any agency thereof, or Battelle Memorial Institute. The views and opinions of authors expressed herein do not necessarily state or reflect those of the United States Government or any agency thereof.
PACIFIC NORTHWEST NATIONAL LABORATORY
operated by
BATTELLE
for the
UNITED STATES DEPARTMENT OF ENERGY
under Contract DE-AC05-76RL01830
Installing CoreMS
How to install CoreMS 4.0+ for normal use, development, optional databases, and Thermo .raw support.
This is the canonical install guide. The README has a short quickstart only. This file is loaded into corems.__doc__ (together with the README) so just docu / pdoc shows it on the package landing page with the same styling as the API docs.
Requirements
| Requirement | Notes |
|---|---|
| Python 3.11–3.14 | From requires-python in pyproject.toml |
| pip | Prefer upgrading: python -m pip install -U pip |
| Optional: Docker | PostgreSQL via docker-compose, or the full CoreMS image |
| Optional: .NET 8 runtime | Host Thermo .raw via Python.NET (see system dependencies) |
Declared Python dependencies (including pythonnet) are installed with the package. You do not need a separate pip install pythonnet.
Quick install (PyPI)
Use an isolated environment (venv or conda). Example with venv:
python -m venv venv
# Windows: venv\Scripts\activate
source venv/bin/activate
python -m pip install -U pip
pip install corems
Verify:
python -c "import corems; print(corems.__version__)"
By default the molecular formula database uses SQLite (local file; no extra services).
Optional extras
Install extras from pyproject.toml as needed:
pip install "corems[dev]" # tests, ruff, docs tooling (incl. pdoc)
With corems[dev], maintainers can format and auto-fix the package via just lint at release time (see RELEASE.md). That command rewrites files.
Check the installed package metadata or pyproject.toml for the current list of extras.
Install from source
git clone https://github.com/EMSL-Computing/CoreMS.git
cd CoreMS
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
python -m pip install -U pip
pip install .
# editable install for development:
# pip install -e ".[dev]"
Internal GitLab (same install after clone):
https://code.emsl.pnl.gov/mass-spectrometry/corems.git
Molecular formula database
SQLite (default)
No extra services. Suitable for most users and light workloads.
PostgreSQL (optional)
For multi-user or higher-load molecular formula search:
- Install and start Docker.
- From the CoreMS repository root:
docker-compose up -d
- Point CoreMS at the database (either approach):
export COREMS_DATABASE_URL="postgresql+psycopg://coremsappdb:coremsapppnnl@localhost:5432/coremsapp"
Or set MSParameters.molecular_search.url_database to the same URL.
Keep Docker running while you use this database.
System dependencies (Thermo .raw)
Reading Thermo .raw files uses Python.NET (a package dependency) plus a .NET runtime on the host. This is separate from pip install.
Recommended: .NET 8 (CoreCLR)
Matches CoreMS CI and the project Dockerfile (.NET 8, not .NET 9).
- Install the .NET 8 runtime for your OS and CPU (x64 or arm64): Download .NET 8.
- Prefer CoreCLR:
export PYTHONNET_RUNTIME=coreclr
# If the runtime is not on the default path:
# export DOTNET_ROOT=/usr/local/dotnet
# export PATH="$PATH:$DOTNET_ROOT"
- Confirm:
dotnet --list-runtimes
# should list a Microsoft.NETCore.App 8.x runtime
On Apple Silicon, install the arm64 .NET 8 runtime when running Python natively on arm64. The CoreMS Docker image already includes .NET 8, so host .NET is optional if you only run inside the image.
Optional: Mono
Some users still use Mono with Python.NET. That path is not required for CoreMS 4.0+. If you use Mono:
export PYTHONNET_RUNTIME=mono
You may also need Mono’s libraries discoverable on your system (distribution-specific). Prefer CoreCLR unless you already depend on Mono.
Windows
pip install coremsinstalls pythonnet with the package.- Install .NET 8 if you need Thermo
.rawsupport; usePYTHONNET_RUNTIME=coreclrwhen required.
Docker image (full application)
To run CoreMS in a container that already includes .NET 8 and dependencies, see Building and Running the CoreMS Docker Image in the README (just build-image-local / just build-image-mac-local on Apple Silicon).
Example notebooks
Workflow examples live under examples/notebooks/. These are intended as demonstrations and starting points for your own analysis.
Troubleshooting
| Symptom | What to check |
|---|---|
import corems fails / wrong Python |
Active venv; python --version is 3.11+ |
Thermo .raw / pythonnet errors |
.NET 8 installed; PYTHONNET_RUNTIME=coreclr; dotnet --list-runtimes |
| Using Mono deliberately | PYTHONNET_RUNTIME=mono; Mono installed |
| PostgreSQL connection errors | docker-compose up -d; COREMS_DATABASE_URL / URL in parameters |
| Apple Silicon Docker builds | macOS image build targets in the README (linux/amd64) |
Building the documentation site
just docu
Opens as docs/corems.html. The landing module page includes this install guide via corems/__init__.py.
See also
- README.md — overview, short install, Docker image
- CONTRIBUTING.md — development workflow and local tests
- RELEASE.md — versioning and releases (maintainers)
- Package / API docs (generated)
1__author__ = "Yuri E. Corilo" 2__version__ = "4.1.0" 3import time 4import os 5import sys 6import hashlib 7 8# Package documentation for pdoc: README plus the full install how-to so the 9# landing page uses the same styling as the rest of the API site. 10_pkg_dir = os.path.dirname(__file__) 11_repo_root = os.path.join(_pkg_dir, "..") 12_fallback_doc = ( 13 "CoreMS: A comprehensive mass spectrometry framework for software " 14 "development and data analysis of small molecules analysis." 15) 16 17_doc_parts = [] 18for _rel in ( 19 "README.md", 20 os.path.join("docs", "user", "installation.md"), 21): 22 _path = os.path.join(_repo_root, _rel) 23 if not os.path.exists(_path): 24 continue 25 try: 26 with open(_path, "r", encoding="utf-8") as _fh: 27 _text = _fh.read().strip() 28 if _text: 29 _doc_parts.append(_text) 30 except Exception as e: 31 print(f"Warning: Could not read {_rel} for package docs. Error: {e}") 32 33__doc__ = "\n\n---\n\n".join(_doc_parts) if _doc_parts else _fallback_doc 34 35 36def timeit(print_time=True): 37 def decorator(method): 38 def timed(*args, **kw): 39 # Extract print_time from kwargs if provided 40 local_print_time = kw.pop("print_time", print_time) 41 ts = time.time() 42 result = method(*args, **kw) 43 te = time.time() 44 if "log_time" in kw: 45 name = kw.get("log_name", method.__name__.upper()) 46 kw["log_time"][name] = int((te - ts) * 1000) 47 elif local_print_time: 48 print("%r %2.2f ms" % (method.__name__, (te - ts) * 1000)) 49 return result 50 51 return timed 52 53 return decorator 54 55 56class SuppressPrints: 57 def __enter__(self): 58 self._original_stdout = sys.stdout 59 sys.stdout = open(os.devnull, "w") 60 61 def __exit__(self, exc_type, exc_val, exc_tb): 62 sys.stdout.close() 63 sys.stdout = self._original_stdout 64 65 66def chunks(lst, n): 67 """Yield successive n-sized chunks from lst.""" 68 for i in range(0, len(lst), n): 69 yield lst[i : i + n] 70 71 72def corems_md5(fname): 73 bytes_io = fname.open("rb").read() 74 75 md5_returned = hashlib.sha256(bytes_io).hexdigest() 76 77 return "{}:{}".format("sha256", md5_returned)
37def timeit(print_time=True): 38 def decorator(method): 39 def timed(*args, **kw): 40 # Extract print_time from kwargs if provided 41 local_print_time = kw.pop("print_time", print_time) 42 ts = time.time() 43 result = method(*args, **kw) 44 te = time.time() 45 if "log_time" in kw: 46 name = kw.get("log_name", method.__name__.upper()) 47 kw["log_time"][name] = int((te - ts) * 1000) 48 elif local_print_time: 49 print("%r %2.2f ms" % (method.__name__, (te - ts) * 1000)) 50 return result 51 52 return timed 53 54 return decorator
67def chunks(lst, n): 68 """Yield successive n-sized chunks from lst.""" 69 for i in range(0, len(lst), n): 70 yield lst[i : i + n]
Yield successive n-sized chunks from lst.