A Python plugin for processing and visualizing in situ NMR data within datalab instances. This plugin leverages the datalab Python API to create interactive Bokeh plots of NMR data alongside electrochemical measurements.
The project was originally developed in and is currently deployed for the Grey Group in the Department of Chemistry at the University of Cambridge.
- Process both 1D and pseudo-2D NMR data from Bruker instruments
- Integration with electrochemical data for combined analysis
- Interactive visualization using Bokeh
- Flexible PPM range selection
- Support for both local files and datalab API access
We recommend you use uv
for managing virtual environments and Python versions.
Once you have uv
installed, you can clone this repository and install the package in a fresh virtual environment with:
git clone [email protected]:datalab-org/datalab-app-plugin-insitu
cd datalab-app-plugin-insitu
uv sync --all-extras --dev
You can activate pre-commit
in your local repository with uv run pre-commit install
.
When using the plugin with a datalab instance, you need to set up your API key:
- Create a .env file in your project root
- Add your Datalab API key:
DATALAB_API_KEY=your_api_key_here
The plugin offers two main processing functions: process_local_data for local files and process_datalab_data for datalab integration.
from datalab_app_plugin_insitu import process_local_data
# Process local NMR data
result = process_local_data(
folder_name="path/to/your/data.zip", # Path to zip file or folder
nmr_folder_name="nmr_data", # Folder containing NMR experiments
echem_folder_name="echem_data", # Optional: folder with electrochemical data
ppm1=240, # Lower PPM range limit
ppm2=280, # Upper PPM range limit
start_at=1, # Optional: starting experiment number
exclude_exp=[] # Optional: experiments to exclude
)
from datalab_app_plugin_insitu import process_datalab_data
# Process NMR data from datalab
result = process_datalab_data(
api_url="https://your-datalab-instance.com",
item_id="your-item-id",
folder_name="your-folder",
nmr_folder_name="nmr-data",
echem_folder_name="echem-data",
ppm1=240,
ppm2=280,
start_at=1, # Optional: starting experiment number
exclude_exp=[] # Optional: experiments to exclude
)
def process_local_data(
folder_name: str,
nmr_folder_name: str,
echem_folder_name: str,
ppm1: float,
ppm2: float,
start_at: int = 1,
exclude_exp: Optional[List[int]] = None,
) -> Dict
Process NMR spectroscopy data from local files.
Parameters:
folder_name
: Path to zip file or folder containing the datanmr_folder_name
: Folder containing NMR experimentsechem_folder_name
: Folder containing electrochemical data (optional)ppm1
: Lower PPM range limitppm2
: Upper PPM range limitstart_at
: Starting experiment number (default: 1)exclude_exp
: List of experiment numbers to exclude (default: None)
def process_datalab_data(
api_url: str,
item_id: str,
folder_name: str,
nmr_folder_name: str,
echem_folder_name: str,
ppm1: float,
ppm2: float,
start_at: int = 1,
exclude_exp: Optional[List[int]] = None,
) -> Dict
Process NMR spectroscopy data from Datalab API.
Parameters:
api_url
: URL of the Datalab APIitem_id
: ID of the item to processfolder_name
: Base folder name in datalabnmr_folder_name
: Folder containing NMR experimentsechem_folder_name
: Folder containing electrochemical data (optional)ppm1
: Lower PPM range limitppm2
: Upper PPM range limitstart_at
: Starting experiment number (default: 1)exclude_exp
: List of experiment numbers to exclude (default: None)
Returns format:
Both functions return a dictionary with the following structure:
result = {
"metadata": {
"ppm_range": {
"start": float, # Minimum PPM value
"end": float # Maximum PPM value
},
"time_range": {
"start": float, # Start time in hours
"end": float # End time in hours
},
"num_experiments": int, # Total number of experiments
},
"nmr_spectra": {
"ppm": List[float], # PPM values
"spectra": [
{
"time": float, # Time point in hours
"intensity": List[float] # Intensity values
}
]
},
"integrated_data": {
"intensity": List[float], # Integrated intensity
"norm_intensity": List[float] # Normalized intensity
"time": float, # Time point in hours
},
"echem": { # Only present if echem_folder_name is provided
"Voltage": List[float], # Voltage measurements
"time": List[float] # Time points in hours
}
}
Your data should be organized as follows:
data_folder.zip/
├── nmr_folder/
│ ├── 1/
│ │ ├── acqus
│ │ └── pdata/
│ │ └── 1/
│ │ └── ascii-spec.txt
│ ├── 2/
│ │ └── ...
│ └── ...
└── echem_folder/ (optional)
└── echem/
└── GCPL_*.MPR
This project is released under the conditions of the MIT license. Please see LICENSE for the full text of the license.
For questions and support, please open an issue on the GitHub repository or join the public datalab Slack workspace.