Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
fbaa71f
fix: conditional header generation for NMR JCAMP export (#219)
Nicolass67 Nov 20, 2024
e7e517b
fix: data normalization and improve handling of runs in JcampMSConver…
Nicolass67 Nov 28, 2024
7fe8777
Bump werkzeug from 3.0.3 to 3.0.6 (#217)
dependabot[bot] Nov 28, 2024
7646522
chore: bump version tag from 1.2.3 to 1.2.4
PiTrem Dec 10, 2024
ef59089
Bump jinja2 from 3.1.4 to 3.1.6
dependabot[bot] Mar 6, 2025
f75ace7
fix: ensure proper line separation for n-tuples end markers in MS JCA…
Nicolass67 Mar 13, 2025
896a531
Merge pull request #224 from ComPlat/dependabot/pip/jinja2-3.1.6
Nicolass67 Mar 20, 2025
51aa1b9
chore: bump version tag from 1.2.4 to 1.2.5
Nicolass67 Mar 20, 2025
a35ab5a
Bump gunicorn from 22.0.0 to 23.0.0
dependabot[bot] Mar 22, 2025
ee6372f
fix: support ESI SIM mass files conversion (#228)
Nicolass67 Mar 25, 2025
f5fcbbb
Merge pull request #227 from ComPlat/dependabot/pip/gunicorn-23.0.0
Nicolass67 Mar 25, 2025
189aac3
chore: bump version tag from 1.2.5 to 1.2.6
Nicolass67 Mar 25, 2025
8686efb
fix: certificates issue
phuang26 Mar 26, 2025
cd691d3
fix: adjust upper margin for IR preview images
Nicolass67 Apr 2, 2025
7dd77ed
Merge pull request #231 from ComPlat/fix/ir-preview-margin
Nicolass67 Apr 9, 2025
79643c2
Merge pull request #229 from ComPlat/certificates-issue
Nicolass67 Apr 9, 2025
9ca45f7
chore(deps): bump requests from 2.32.2 to 2.32.4 (#236)
dependabot[bot] Jul 29, 2025
087b5b8
fix: skip empty JCAMP files in BagIt converter to prevent 500 error …
Nicolass67 Jul 29, 2025
03dddc7
fix: Add $CSSOLVENT* metadata to align simulated NMR peaks with spect…
Nicolass67 Jul 29, 2025
c3e1c7f
chore(deps): bump urllib3 from 1.26.19 to 2.5.0 (#237)
dependabot[bot] Jul 29, 2025
3d25c49
build: migrate to pyproject.toml with loose dependency versioning and…
harivyasi Aug 13, 2025
a2bef30
chore: prepare v1.3.0 (#246)
PiTrem Aug 13, 2025
7a39189
ci: push2deploy (#245)
harivyasi Aug 13, 2025
7d01c72
ci (push2deploy): fix: add `curl` to dockerfile (#247)
harivyasi Aug 13, 2025
65247ff
fix: replace invalid non-ASCII CURPLOT lines in test fixtures (#249)
Nicolass67 Sep 9, 2025
89c3b17
chore: update nmrglue dependency to include fixes for XYPOINTS and UT…
Nicolass67 Sep 9, 2025
a8d16a2
fix: handle incomplete Bruker pdata folders (#239)
Nicolass67 Sep 9, 2025
9c49c53
chore: Bump version from 1.3.0 to 1.3.1
PiTrem Sep 9, 2025
77dd6c8
fix(ms): set figure dpi to 200 for MS images for consistency (#253)
Nicolass67 Oct 7, 2025
553e8e4
fix: remove Bruker 'ser' fallback in search_brucker_binary (#252)
Nicolass67 Oct 7, 2025
ba7a063
chore: Bump version from 1.3.1 to 1.3.2 (#254)
Nicolass67 Oct 7, 2025
4c8caf8
Improved devcontainer setup (#256)
harivyasi Nov 17, 2025
03e3fca
refactor: remove unused NMRium generation and harden parsing (#259)
Nicolass67 Jan 27, 2026
9eccbb8
upd: update label in image for multiple nmr (#209)
baolanlequang Aug 19, 2024
f62cfd7
feat WIP: handle zip lcms
Aug 27, 2024
5fed364
feat WIP: process tic positive and negative
Sep 2, 2024
4b75351
feat WIP: read lcms and transform to jcamp
Sep 4, 2024
2153ade
feat WIP: process hplc ms
Sep 4, 2024
a0e85ac
chore: refactor
Sep 4, 2024
51a88e1
Feat:
Nicolass67 Aug 25, 2025
be3ffb0
WIP save integrals
Nicolass67 Oct 29, 2025
855be5d
Update file_container.py
Nicolass67 Nov 5, 2025
b319cb6
Add BinaryParser
Nicolass67 Nov 5, 2025
20aabb2
Revert "WIP save integrals"
Nicolass67 Nov 6, 2025
91cb88a
Integrate chemotion-converter-app for OpenLab LCMS ZIPs
Nicolass67 Jan 19, 2026
82e0820
Add support for tarball archives in TransformerModel
Nicolass67 Jan 19, 2026
0d8f16a
Refactor LCMS handling: replace LCMSComposer with LCMSConverterAppCom…
Nicolass67 Feb 4, 2026
d84fdc5
Add UVVIS symbol header for LCMS profiles
Nicolass67 Feb 4, 2026
e707278
Disable _auto_peaks function from chemotion_converter_lcms.py
Nicolass67 Feb 9, 2026
1c99576
Enhance LCMSConverterAppComposer and TransformerModel to support UVVI…
Nicolass67 Feb 9, 2026
f26a95d
indent typo
Nicolass67 Feb 9, 2026
b9f5054
Implement zip_jcamp_n_img endpoint to handle file uploads and generat…
Nicolass67 Feb 16, 2026
1b1b50d
Add filename normalization for LCMS files in file_api.py and implemen…
Nicolass67 Feb 16, 2026
716361d
Remove unused 'lcms_tic' parameter from extract_params and parse_para…
Nicolass67 Feb 23, 2026
1d149be
Update LCMS preview image handling in chemotion_converter_lcms.py to …
Nicolass67 Feb 23, 2026
836f9b3
chore: Bump version from 1.3.2 to 1.3.3
PiTrem Feb 27, 2026
79871f9
feat(CV): current density axis toggle (#262)
Nicolass67 Feb 28, 2026
5ecf77b
chore: Bump version from 1.3.3 to 1.4.0
PiTrem Feb 28, 2026
7017cd5
Add lcms_mz_page_data parameter handling in extract_params and parse_…
Nicolass67 Mar 6, 2026
9adb6aa
Enhance LCMS preview image generation in chemotion_converter_lcms.py …
Nicolass67 Mar 6, 2026
2e12aea
Remove the unused lcms_uvvis_image_from_peak_jdx function
Nicolass67 Mar 16, 2026
ac10ba0
feat(converter): remote Chemotion jcampzip conversion for LCMS raw ar…
Nicolass67 Mar 23, 2026
ec9ca0b
Update converter configuration in chem_spectra
Nicolass67 Apr 1, 2026
67c4fe6
Enhance LCMS data handling in chemotion_converter_lcms.py by adding s…
Nicolass67 Apr 15, 2026
11e5456
Refactor LCMSConverterAppComposer to improve handling of LCMS mz page…
Nicolass67 Apr 15, 2026
65ae7cf
Remove temporary subprojects and refactor LCMS handling in chem_spect…
Nicolass67 Apr 20, 2026
f0b6be1
Refactor LCMS response handling to utilize flat BagIt zip structure. …
Nicolass67 Apr 20, 2026
d3e7f5f
Enhance LCMS response handling in transform_api.py by integrating LCM…
Nicolass67 Apr 20, 2026
beda75b
Refactor TransformerModel to streamline LC/MS and HPLC UVVIS handling
Nicolass67 Apr 20, 2026
7ad94c2
Refactor LCMS handling to improve peak file management and enhance re…
Nicolass67 May 18, 2026
27938fb
chore: relicense from AGPL-3.0 to MIT (#267)
PiTrem May 29, 2026
89a23f3
Fix LCMS UV-Vis units in peak files and preview X-axis scaling
Nicolass67 Jun 10, 2026
6411ac8
Merge remote-tracking branch 'origin/master' into 211-process-lcms-data
Nicolass67 Jun 10, 2026
a758899
Address Copilot review feedback on LCMS response typing and peak file…
Nicolass67 Jun 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .devcontainer/Dockerfile.devcontainer
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM python:3.12-slim AS base

# Install any additional OS packages you want in addition to sudo, git and nano
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=apt-cache \
--mount=type=cache,target=/var/lib/apt,sharing=locked,id=apt-lib \
apt-get update && \
apt-get install -y --no-install-recommends \
sudo git nano \
# required
gcc g++ libxrender1 libxext6 libglib2.0-0

ARG USERNAME=debian

# add default user with no password and sudo privilege
RUN useradd -m --shell /bin/bash $USERNAME && passwd -d ${USERNAME} && adduser ${USERNAME} sudo

USER $USERNAME
WORKDIR /home/${USERNAME}

ENV PIP_CACHE_DIR=./.cache/pip
ENV PIP_USER=1
ENV PIP_NO_WARN_SCRIPT_LOCATION=1

RUN mkdir -p ${PIP_CACHE_DIR}

# to be replaced later by ADD git#branch if needed
COPY pyproject.toml .

RUN --mount=type=cache,target=${PIP_CACHE_DIR},sharing=locked,id=pip-cache \
touch README.md && pip install --upgrade pip && pip install .[dev] && rm -rf README.md pyproject.toml build *.egg-info
35 changes: 35 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "ChemSpectraApp",
"build": {
"dockerfile": "Dockerfile.devcontainer",
"context": ".."
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [
3007 // Port for the web server
],
// Ensure the environment
"postStartCommand": "pip install --upgrade pip && pip install --upgrade .[dev] && pip freeze > dependencies.list",
"remoteUser": "debian",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/debian/chem_spectra,type=bind",
"workspaceFolder": "/home/debian/chem_spectra",
// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.autopep8",
"ms-python.vscode-pylance",
"github.vscode-github-actions"
],
"settings": {
"[python]": {
"python.defaultInterpreterPath": "/usr/local/bin/python",
"editor.defaultFormatter": "ms-python.autopep8"
},
"editor.formatOnSave": true
}
}
}
}
29 changes: 19 additions & 10 deletions .github/workflows/unit_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,28 @@ jobs:
run-unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.8
uses: actions/setup-python@v4
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: 3.8
check-latest: true
cache: "pip"
python-version: "3.12"
- name: Install dependencies
uses: conda-incubator/setup-miniconda@v3
with:
activate-environment: python-v38
environment-file: environment.yml
miniforge-version: latest
run: |
pip install --upgrade pip
pip install .[dev]
- name: Create tmp directory with permissions
run: |
mkdir -p chem_spectra/tmp
chmod -R 777 chem_spectra/tmp
- name: Start msconvert Docker container
run: |
docker run --detach --name msconvert_docker \
--rm -it \
-e WINEDEBUG=-all \
-v ${{ github.workspace }}/chem_spectra/tmp:/data \
proteowizard/pwiz-skyline-i-agree-to-the-vendor-licenses bash
- name: Test with pytest
shell: bash -el {0}
run: |
conda activate python-v38
python -m pytest
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
venv/
.venv/
.cache/

*.pyc
__pycache__/
Expand Down
12 changes: 0 additions & 12 deletions .travis.yml

This file was deleted.

46 changes: 46 additions & 0 deletions Dockerfile.p2d
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
FROM python:3.12-slim AS base

# Install any additional OS packages you want in addition to sudo, git and nano
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=apt-cache \
--mount=type=cache,target=/var/lib/apt,sharing=locked,id=apt-lib \
apt-get update \
&& apt-get install -y --no-install-recommends \
sudo git nano curl \
gcc g++ libxrender1 libxext6 libglib2.0-0 # required

ADD --chmod=755 https://payload.chemserv.scc.kit.edu/fake-docker.py /bin/docker
ADD https://payload.chemserv.scc.kit.edu/spectra_config.py /app/instance/config.py

WORKDIR /app

RUN mkdir -p /var/cache/pip

ENV PIP_CACHE_DIR=/var/cache/pip \
PIP_ROOT_USER_ACTION=ignore

COPY pyproject.toml .

RUN --mount=type=cache,target=/var/cache/pip,sharing=locked,id=pip-cache \
pip install --upgrade pip && pip install .

COPY ./chem_spectra /app/chem_spectra
COPY ./server.py /app/server.py

# Finalize app setup
RUN mkdir -p /shared /app/instance && \
ln -s /shared /app/chem_spectra/tmp

ENV FLASK_ENV=production \
FLASK_DEBUG=0 \
MSC_HOST=msconvert \
MSC_PORT=4000 \
MSC_VALIDATE=true \
SPECTRA_PORT=4000

EXPOSE 4000

CMD ["gunicorn", "--timeout", "600", "-w", "4", "-b", "0.0.0.0:4000", "server:app"]
# i.e the command: gunicorn --timeout 600 -w 4 -b 0.0.0.0:4000 server:app

HEALTHCHECK --interval=5s --timeout=3s --start-period=30s --retries=3 \
CMD curl --fail http://localhost:4000/ping || exit 1
135 changes: 43 additions & 92 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,86 +4,56 @@ This guidance is tested on Linux Ubuntu 18.04 & Ubuntu 20.04

## 1. Installation

### 1.1. Install Anaconda & Docker
### 1.1. Install Python

Please refer to [https://www.anaconda.com/] & [https://docs.docker.com/install/].
Use the file pyproject.toml to determine the version of Python required.

You can follow [unofficial Anaconda & Docker installations for Dummies](INSTALL_BASIC.md) for a test installation.
### 1.2. Clone repository and create env

However, it is highly recommended to refer to official websites.

### 1.2. Create env

_Logout & login to load installations._

```
$ conda create --name chem-spectra python=3.8
$ source activate chem-spectra
```

```
$ sudo apt-get install gcc libxrender1 libxext-dev pkg-config g++
```

```
$ git clone https://github.com/ComPlat/chem-spectra-app.git
$ cd chem-spectra-app
$ pip install -r requirements.txt
```sh
git clone https://github.com/ComPlat/chem-spectra-app.git
cd chem-spectra-app
```

The project is in `~/chem-spectra-app`.


### 1.3. Use msconvert in Docker
ALL the **FOLLOWING** commands are assumed to be executed while inside this
`chem-spectra-app` folder.

```
$ docker pull chambm/pwiz-skyline-i-agree-to-the-vendor-licenses
python3 -m venv .venv && .venv/bin/pip install --upgrade pip
source .venv/bin/activate
pip install .
```

__Make sure you are in the `chem-spectra-app` folder.__
```
$ cd ~/chem-spectra-app
```
### 1.3. Use docker to run a supporting service

```
$ mkdir chem_spectra/tmp
$ sudo chmod -R 755 chem_spectra/tmp
```
To running docker for converting Mass spectrum, run this command:
```
$ docker run --detach --name msconvert_docker \
--rm -it \
-e WINEDEBUG=-all \
-v [YOUR LOCATION TO chem-spectra-app]/chem_spectra/tmp:/data \
chambm/pwiz-skyline-i-agree-to-the-vendor-licenses bash
```

For example, if your location of `chem-spectra-app` is `/home/ubuntu/chem-spectra-app`
```
$ docker run --detach --name msconvert_docker \
```sh
docker pull proteowizard/pwiz-skyline-i-agree-to-the-vendor-licenses
mkdir -p chem_spectra/tmp
chmod -R 755 chem_spectra/tmp
docker run --detach --name msconvert_docker \
--rm -it \
-e WINEDEBUG=-all \
-v /home/ubuntu/chem-spectra-app/chem_spectra/tmp:/data \
chambm/pwiz-skyline-i-agree-to-the-vendor-licenses bash
-v ./chem_spectra/tmp:/data \
proteowizard/pwiz-skyline-i-agree-to-the-vendor-licenses bash
```

### 1.4. Add `config.py`

Generate a secret key.

```
$ python -c 'import os; print(os.urandom(16))'
```sh
python -c 'import os; print(os.urandom(16))'
>> b'T\x1d\xb3\xfe\xb6q\xef\xbf\x7f\xcaj\xcbZ\x84\x1ee'
```

Create `config.py`.

```
$ mkdir -p ./instance && touch ./instance/config.py
$ vim ./instance/config.py
```sh
mkdir -p ./instance && touch ./instance/config.py
nano ./instance/config.py
```

Add content.
Add the following content.

```python
# ./instance/config.py
Expand All @@ -99,23 +69,22 @@ MAX_ZIP_SIZE = 100 #maximum size of a zip file in MB to prevent zip bomb, defaul

Using only "one" of following commands.

```
```sh
# run on the production server
$ gunicorn -w 4 -b 0.0.0.0:3007 server:app --daemon
gunicorn -w 4 -b 0.0.0.0:3007 server:app --daemon
```


```
```sh
# for local development only
$ export FLASK_APP=chem_spectra && export FLASK_DEBUG=true && flask run --host=0.0.0.0 --port=3007
export FLASK_APP=chem_spectra && export FLASK_DEBUG=true && flask run --host=0.0.0.0 --port=3007
```

### 1.6 Quick test

You should receive `pong` when executing the following command from another machine.

```
$ curl xxx.xxx.xxx.xxx:3007/ping
```sh
curl xxx.xxx.xxx.xxx:3007/ping
```

## 2. Usage
Expand All @@ -130,63 +99,45 @@ body = { file: target.jdx }
```

### 2.1. Logging
By default, the logging file is at
```
./instance/logging.log
```

By default, the logging file is at `./instance/logging.log`.

### 2.2. Implement a new log message

Import `logging` package at where you want to write your log message

```
import logging
```

Write log message as

```
logger = logging.getLogger(__name__)
logger.setLevel(logging.ERROR) //levels: DEBUG, INFO, ERROR, WARNING, CRITICAL
logger.error('message to log')
```
Note: You need to use function as the same as your logger level, which named as lowercased of level's name, to write your log message to the logs file

Note: You need to use function as the same as your logger level, which named as lowercased of level's name, to write your log message to the logs file

### 2.3. Automatic startup in crontab

To make sure ChemSpectra is started on reboot you can use this BASH script in your root crontab (if required, adapt Chemotion ELN username and home directory):

```sh
#!/bin/bash

sudo -H -u production bash -c "cd /home/production/chem-spectra-app && \
source /home/production/anaconda3/bin/activate chem-spectra && \
gunicorn -w 4 -b 0.0.0.0:3007 server:app --daemon"

# Remember to modify path according to your installation
cd /path/to/chem-spectra-app
source .venv/bin/activate
docker run --detach --name msconvert_docker \
--rm -it \
-e WINEDEBUG=-all \
-v /home/production/chem-spectra-app/chem_spectra/tmp:/data chambm/pwiz-skyline-i-agree-to-the-vendor-licenses \
-v ./chem_spectra/tmp:/data proteowizard/pwiz-skyline-i-agree-to-the-vendor-licenses \
bash
gunicorn -w 4 -b 0.0.0.0:3007 server:app --daemon
```

## 3. Run test

```
$ coverage run -m pytest --disable-pytest-warnings
$ coverage report
```

## 4. Linting

```
$ flake8
```


## DEBUG

### msconvert_docker

```
$ docker exec -it msconvert_docker wine msconvert --help
```sh
python -m pytest
```
Loading