Code and dataset for "From Berzelius to hyperspace: Previously unrecognized network of reactivity in textbook brominations "
收藏资源简介:
bruce-nmr-station An automated NMR laboratory station for scanning reaction conditions and building reaction hyperspaces. The system integrates a robotic arm, an automated liquid handler, and a benchtop NMR spectrometer to autonomously prepare samples, acquire spectra, and calculate chemical yields — with minimal human intervention. https://www.image2url.com/r2/default/images/1781093549801-e75dc8b7-b3fa-4c3c-8764-370a744724b2.jpg Publication This repository contains the automation and data-treatment code supporting: Yankai Jia, Wai-Shing Wong, Yasemin Bilgi-Gadina, Louis P. J.-L. Gadina, King-Lam Kwong, Yanqiu Jiang, Nikolaos Vagkidis, Benito Marazzi, Peter R. Schreiner, and Bartosz A. Grzybowski. "From Berzelius to hyperspace: Unexpected reactivity in textbook brominations." Overview The platform operates in two stages: 1. Automation (nmr-station/) — A Flask web app + scheduler orchestrates three hardware devices: ○ Robot arm picks up and transports sample tubes ○ Pipetter aspirates reaction samples into measurement tubes ○ NMR spectrometer acquires 1H spectra on demand ○ NMR tubes are automatically cleaned and dried after each measurement 2. Data Treatment (data-treatment/) — A post-processing pipeline calculates chemical yields: ○ Integrates NMR peaks with baseline correction ○ Interpolates concentrations from 2D calibration curves ○ Exports yield, conversion, and selectivity metrics to CSV 3. Raw Data (data/) — NMR run folders archived on Zenodo (not stored in this repository): ○ One subfolder per reaction campaign (e.g. DPE_bromination/) ○ Each run folder contains raw spectra, plate-map Excel files, and pipeline outputs ○ Download from: https://doi.org/10.5281/zenodo.17080099 4. DFT Data (dft-data/) — The raw data for the computational results reported in Section 6 of the Supplementary Information are collected here: ○ SI 6.2 Open Carbocation vs Cyclic Bromonium Ion/ — Gaussian output files (.log) for carbocation intermediates C1+, C3+, C5+, C8+, C9+ ○ SI 6.3 Diastereoselectivity of Dibromination of BDA/ — Gaussian output files for ion-pair complex geometry optimisations (Figures S68–S75), covering anti/syn approach with bromide and tribromide counterions System Architecture ┌─────────────────────────────────────────────────────────────┐ │ nmr-station/ │ │ │ │ app.py (Flask UI) ──► scheduler.py (Orchestrator) │ │ │ │ │ ┌────────────────┼────────────────┐ │ │ ▼ ▼ ▼ │ │ robotic_arm/ spectrometer/ pipetter/ │ │ Meca500 Spinsolve 80 miniPi │ │ (TCP/IP) (TCP/IP XML) (Serial) │ └─────────────────────────────────────────────────────────────┘ │ NMR spectra │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ data-treatment/ │ │ │ │ main.py ──► Integrator ──► conc_interpolation │ │ │ │ │ Yield / Selectivity CSV │ └─────────────────────────────────────────────────────────────┘ │ outputs │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ data/ (git-ignored) │ │ │ │ DPE_bromination/ │ │ └── YYYY-MM-DD-runXX_<solvent>_<additive>/ │ │ ├── Results/ (fitting_results.json, interp_conc.json)│ │ ├── <spectra folders>/ │ │ └── out_concentrations.csv │ └─────────────────────────────────────────────────────────────┘ Hardware Requirements Device Model Connection Robot arm Mecademic Meca500 TCP/IP — 192.168.0.100 NMR spectrometer Spinsolve 80 MHz TCP/IP — 127.0.0.1:13000 (XML protocol) Liquid handler miniPi (GRBL-based) Serial (USB) Software Requirements ● Python: 3.10 ● Environment manager: Conda (environment named brucelee) Key packages: Package Purpose mecademicpy Mecademic robot arm control nmrglue NMR spectrum reading and processing Flask Web UI for automation control PySimpleGUI Desktop dialogs for data treatment pyserial Serial communication with pipetter Installation 1. Clone the repository git clone <repo-url>cd bruce-nmr-station 2. Download the raw data from Zenodo The experimental NMR dataset is archived at: https://doi.org/10.5281/zenodo.17080099 Download and extract the archive so that it contains a DPE_bromination/ folder at the top level. Then point the pipeline to it in one of two ways: Option A — environment variable (recommended): # Windowsset BRUCELEE_DATA_ROOT=C:\path\to\extracted\data# macOS / Linuxexport BRUCELEE_DATA_ROOT=/path/to/extracted/data Option B — edit data-treatment/config.py directly: DATA_ROOT = r"C:\path\to\extracted\data" # change this line If neither is set, the pipeline defaults to the data/ folder at the repository root. 4. Create the conda environment conda env create -f environment.ymlconda activate brucelee 5. Configure hardware environment variables Fill in the settings file at nmr-station/settings/.env: ROBOT_ARM_HOST=192.168.0.100 ROBOT_ARM_LOG_PATH=<path-to-log-folder> SPECTROMETER_REMOTE_CONTROL_HOST=127.0.0.1 SPECTROMETER_REMOTE_CONTROL_PORT=13000 ROBOCHEM_DATA_PATH=<path-to-data-root> PIPETTER_LOG_PATH=<path-to-pipetter-log> MEASUREMENT_DATA_GUI_PATH=<path-to-gui-state-json> 6. Configure robot arm coordinates Edit nmr-station/robotic_arm/facility_config.json to match the physical positions of: ● Tube racks (tube1–tube4) ● Washer stations (washer1, washer2) ● Dryer ● Spectrometer insertion point (spinsolve) ● Waste collector and flip stands ● Reference sample slot Usage Run the automation (web UI mode) python nmr-station/app.py Open http://localhost:5000 in a browser. Select a protocol (1D PROTON, 1D EXTENDED+, 1D WET SUP), configure parameters, set the sample order, and click Start Automation. Run the automation (direct scheduler mode) python nmr-station/scheduler.py A GUI checklist will guide you through pre-flight checks (WiFi, vacuum, solvent levels, etc.), then automatically begin the measurement sequence. Run data treatment (yield calculation) python data-treatment/main.py A dialog will prompt for: ● Reaction name, user name, well plate number ● Reaction solvent ● Excel file with reaction conditions and container UUIDs ● Vials to process (e.g. 0-5, 7, 10-12) Results are exported as a CSV with yield, conversion, and selectivity for each sample. Testing without hardware Substitute real device modules with dummies in nmr-station/tests/: from tests.dummy_robotarm import RobotArmfrom tests.dummy_pipetter import Pipetterfrom tests.dummy_spectrometer import Spectrometer Project Structure bruce-nmr-station/ │ ├── nmr-station/ # Automation & hardware control │ ├── app.py # Flask web application │ ├── scheduler.py # Core orchestration engine │ ├── scheduler_Benito.py # User-specific scheduler variants │ ├── robotic_arm/ # Mecademic Meca500 control │ │ ├── roboarm.py # Main robot arm interface │ │ ├── meca.py # Low-level Mecademic wrapper │ │ ├── facility.py # Lab layout and position management │ │ └── facility_config.json # Physical coordinate configuration │ ├── spectrometer/ # Spinsolve NMR control │ │ ├── spectrometer.py # Remote control interface │ │ └── xml_converter.py # XML protocol builder │ ├── pipetter/ # miniPi liquid handler control │ │ ├── pipetter.py # Main pipetter interface │ │ ├── breadboard.py # Hardware-level control │ │ └── grbl/ # Motion controller firmware files │ ├── shared_state/ # Thread-safe inter-device communication │ ├── settings/ # .env and config loader │ ├── templates/ # Jinja2 HTML templates (web UI) │ ├── tests/ # Dummy device implementations │ └── deprecated/ # Legacy code (kept for reference) │ ├── data-treatment/ # NMR data analysis pipeline │ ├── main.py # Pipeline entry point │ ├── config.py # Paths, outlier lists, chemistry config │ ├── Integrator_v3_baseline.py # Python peak integration with baseline correction │ ├── peak_assignment_for_BDA.py # Species-specific peak assignment │ ├── conc_interpolation.py # 1D concentration interpolation │ ├── conc_interpolation_2D.py # 2D RBF calibration curve interpolation │ ├── utils.py # Shared utilities │ ├── MNova_script/ # QtScript for MNova peak fitting (alternative to Integrator) │ ├── TBABr_pipeline.ipynb # Example notebook for TBABr runs end-to-end │ └── old_scripts/ # Legacy analysis scripts │ ├── data/ # Raw NMR data — download from Zenodo (https://doi.org/10.5281/zenodo.17080099) │ └── DPE_bromination/ # DPE bromination reaction campaign │ ├── YYYY-MM-DD-runXX_*/ # One folder per automated run │ │ ├── Results/ # Pipeline outputs (fitting_results.json, interp_conc.json, …) │ │ ├── <spectrum folders>/ # Raw 1H NMR spectra (data.csv per spectrum) │ │ ├── out_concentrations.csv # Reagent concentrations from plate map │ │ └── *.xlsx # Plate map with vial UUIDs and conditions │ ├── NMR_calibration_*/ # Calibration reference runs (no additive) │ └── README.md # Campaign-level documentation │ ├── dft-data/ # DFT raw data for SI Section 6 │ ├── SI 6.2 Open Carbocation vs Cyclic Bromonium Ion/ │ │ └── C1+.log, C3+.log, … # Gaussian output files for carbocation intermediates │ └── SI 6.3 Diastereoselectivity of Dibromination of BDA/ │ ├── Figure S68–S75/ # Ion-pair complex optimisations (anti/syn, bromide/tribromide) │ └── … │ ├── environment.yml # Conda environment specification └── README.md Data Treatment Pipeline NMR spectra (Bruker format) │ ▼ Integrator_v3_baseline.py - Baseline correction - Peak detection and integration │ ▼ conc_interpolation_2D.py - 2D spline calibration curve - Area → concentration conversion │ ▼ optional:peak_assignment_for_BDA.py - Rule-based peak assignment per species - Stoichiometric area constraints - Collision resolution for overlapping peaks │ ▼ Yield / Selectivity / Conversion - CSV export with per-sample metrics - Outlier filtering by UUID Configuration Reference File Purpose nmr-station/settings/.env Hardware connection settings and file paths nmr-station/robotic_arm/facility_config.json Physical robot arm coordinates data-treatment/config.py DATA_ROOT path (override with BRUCELEE_DATA_ROOT env var), outlier UUIDs, NMR peak parameters, compound mappings environment.yml Full pinned conda environment



