From 8aef07202858d79a5a0d39fb2d9e2116a45d7310 Mon Sep 17 00:00:00 2001 From: Venkata Nainala Date: Tue, 29 Sep 2026 08:55:43 +0100 Subject: [PATCH 1/2] feat: include atom shifts in nmrshift predictions The spectrum response dropped the atom-to-shift map, so clients could not label atoms or mark the matching peaks. --- .../engines/nmrshift/nmrshift.engine.ts | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/app/scripts/nmr-cli/src/prediction/engines/nmrshift/nmrshift.engine.ts b/app/scripts/nmr-cli/src/prediction/engines/nmrshift/nmrshift.engine.ts index 8e22e8e..2e906b2 100644 --- a/app/scripts/nmr-cli/src/prediction/engines/nmrshift/nmrshift.engine.ts +++ b/app/scripts/nmr-cli/src/prediction/engines/nmrshift/nmrshift.engine.ts @@ -176,6 +176,52 @@ async function predictNMR( } } + for (let i = 0; i < results.length; i++) { + const response: PredictionResponse = results[i].data + const experimentInfo = experiments[i] + + for (const item of response.result) { + const data = generatePredictedSpectrumData(item.shifts, { + from, + to, + nbPoints, + lineWidth, + frequency, + tolerance, + peakShape, + }) + + if (!data) continue + + const name = crypto.randomUUID() + + outputSpectra.push({ + id: crypto.randomUUID(), + data, + info: { + isFid: false, + isComplex: false, + dimension: 1, + originFrequency: frequency, + baseFrequency: frequency, + pulseSequence: '', + solvent, + isFt: true, + name, + nucleus: experimentInfo.nucleus, + // Kept so clients can label atoms and mark the matching peaks. + // NMRShiftDB atom numbers are 1-based and follow openchemlib's + // addImplicitHydrogens order. + predictionShifts: item.shifts.map(shift => ({ + atom: shift.atom, + prediction: shift.prediction, + status: shift.status, + })), + }, + } as unknown as Spectrum) + } + } + return outputSpectra } From 332c1770e33c0994e777988018e68f5d49083885 Mon Sep 17 00:00:00 2001 From: hamed musallam Date: Fri, 2 Oct 2026 11:51:20 +0200 Subject: [PATCH 2/2] refactor(nmrshift): extract prediction shifts helper --- .../engines/nmrshift/nmrshift.engine.ts | 57 ++++--------------- 1 file changed, 12 insertions(+), 45 deletions(-) diff --git a/app/scripts/nmr-cli/src/prediction/engines/nmrshift/nmrshift.engine.ts b/app/scripts/nmr-cli/src/prediction/engines/nmrshift/nmrshift.engine.ts index 2e906b2..9386b4b 100644 --- a/app/scripts/nmr-cli/src/prediction/engines/nmrshift/nmrshift.engine.ts +++ b/app/scripts/nmr-cli/src/prediction/engines/nmrshift/nmrshift.engine.ts @@ -1,6 +1,6 @@ import type { Options } from 'yargs' import type { Spectrum } from '@zakodium/nmrium-core' -import https from 'https' +import https from 'node:https' import axios, { type AxiosResponse } from 'axios' import { defineEngine } from '../registry.js' @@ -63,6 +63,15 @@ function getBaseUrl(): string { return url } +function getPredictionShifts(shifts: ShiftsItem[]) { + // NMRShiftDB atom numbers are 1-based and follow openchemlib's addImplicitHydrogens order. + return shifts.map(({ atom, prediction, status }) => ({ + atom, + prediction, + status, + })) +} + async function callPredict( structure: string, options: { @@ -155,43 +164,7 @@ async function predictNMR( if (!data) continue - const name = crypto.randomUUID() - - outputSpectra.push({ - id: crypto.randomUUID(), - data, - info: { - isFid: false, - isComplex: false, - dimension: 1, - originFrequency: frequency, - baseFrequency: frequency, - pulseSequence: '', - solvent, - isFt: true, - name, - nucleus: experimentInfo.nucleus, - }, - } as unknown as Spectrum) - } - } - - for (let i = 0; i < results.length; i++) { - const response: PredictionResponse = results[i].data - const experimentInfo = experiments[i] - - for (const item of response.result) { - const data = generatePredictedSpectrumData(item.shifts, { - from, - to, - nbPoints, - lineWidth, - frequency, - tolerance, - peakShape, - }) - - if (!data) continue + const predictionShifts = getPredictionShifts(item.shifts) const name = crypto.randomUUID() @@ -210,13 +183,7 @@ async function predictNMR( name, nucleus: experimentInfo.nucleus, // Kept so clients can label atoms and mark the matching peaks. - // NMRShiftDB atom numbers are 1-based and follow openchemlib's - // addImplicitHydrogens order. - predictionShifts: item.shifts.map(shift => ({ - atom: shift.atom, - prediction: shift.prediction, - status: shift.status, - })), + predictionShifts, }, } as unknown as Spectrum) }