nmr-processing 9.2.0 → 9.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
  [![build status][ci-image]][ci-url]
5
5
  [![Test coverage][codecov-image]][codecov-url]
6
6
  [![npm download][download-image]][download-url]
7
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.5153274.svg)](https://doi.org/10.5281/zenodo.5153274)
7
8
 
8
9
  ## Introduction
9
10
 
package/lib/index.d.ts CHANGED
@@ -20,6 +20,7 @@ export * from './signals/signalsToRanges';
20
20
  export * from './signals/signalsToXY';
21
21
  export * from './signals/signals2DToZ';
22
22
  export * from './signals/optimizeSignals';
23
+ export * from './signals/signalsToFID';
23
24
  export * from './utilities/resurrect';
24
25
  export * from './utilities/rangeFromSignal';
25
26
  export * from './utilities/getFrequency';
package/lib/index.js CHANGED
@@ -36,6 +36,7 @@ __exportStar(require("./signals/signalsToRanges"), exports);
36
36
  __exportStar(require("./signals/signalsToXY"), exports);
37
37
  __exportStar(require("./signals/signals2DToZ"), exports);
38
38
  __exportStar(require("./signals/optimizeSignals"), exports);
39
+ __exportStar(require("./signals/signalsToFID"), exports);
39
40
  __exportStar(require("./utilities/resurrect"), exports);
40
41
  __exportStar(require("./utilities/rangeFromSignal"), exports);
41
42
  __exportStar(require("./utilities/getFrequency"), exports);
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,yDAAuC;AACvC,+DAA6C;AAE7C,gEAA8C;AAC9C,oDAAkC;AAClC,mDAAiC;AAEjC,6DAA2C;AAC3C,6DAA2C;AAC3C,2DAAyC;AACzC,2DAAyC;AACzC,2DAAyC;AACzC,0DAAwC;AACxC,iEAA+C;AAE/C,gEAA8C;AAC9C,iEAA+C;AAC/C,8DAA4C;AAE5C,uDAAqC;AACrC,sDAAoC;AAEpC,4DAA0C;AAC1C,wDAAsC;AACtC,yDAAuC;AACvC,4DAA0C;AAE1C,wDAAsC;AACtC,8DAA4C;AAC5C,2DAAyC;AAEzC,0DAAwC;AACxC,2DAAyC;AACzC,2DAAyC;AAEzC,4DAA0C;AAC1C,wDAAsC;AAEtC,0DAAwC;AACxC,+DAA6C;AAC7C,+DAA6C;AAE7C,6DAA2C;AAC3C,6DAA2C;AAE3C,4DAA0C"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,yDAAuC;AACvC,+DAA6C;AAE7C,gEAA8C;AAC9C,oDAAkC;AAClC,mDAAiC;AAEjC,6DAA2C;AAC3C,6DAA2C;AAC3C,2DAAyC;AACzC,2DAAyC;AACzC,2DAAyC;AACzC,0DAAwC;AACxC,iEAA+C;AAE/C,gEAA8C;AAC9C,iEAA+C;AAC/C,8DAA4C;AAE5C,uDAAqC;AACrC,sDAAoC;AAEpC,4DAA0C;AAC1C,wDAAsC;AACtC,yDAAuC;AACvC,4DAA0C;AAC1C,yDAAuC;AAEvC,wDAAsC;AACtC,8DAA4C;AAC5C,2DAAyC;AAEzC,0DAAwC;AACxC,2DAAyC;AACzC,2DAAyC;AAEzC,4DAA0C;AAC1C,wDAAsC;AAEtC,0DAAwC;AACxC,+DAA6C;AAC7C,+DAA6C;AAE7C,6DAA2C;AAC3C,6DAA2C;AAE3C,4DAA0C"}
@@ -0,0 +1,42 @@
1
+ import { NMRSignal1D } from './NMRSignal1D';
2
+ export interface SignalsToFIDOptions {
3
+ /**
4
+ * at the end of the superposition of all component, an exponential apodization will be applied
5
+ * in order to have FID like shape.
6
+ * @default 1
7
+ */
8
+ lb?: number;
9
+ /**
10
+ * lower limit of the spectrum
11
+ * @default 0
12
+ */
13
+ from?: number;
14
+ /**
15
+ * upper limit of the spectrum
16
+ * @default 10
17
+ */
18
+ to?: number;
19
+ /**
20
+ * number of points of the resulting FID
21
+ */
22
+ nbPoints?: number;
23
+ /**
24
+ * It is the frequency of the carrier (e.g. SFO1 for bruker spectrometers)
25
+ */
26
+ frequency?: number;
27
+ /**
28
+ * Maximum number of atoms on each cluster that can be considered to be simulated together.
29
+ * It affects the the quality and speed of the simulation.
30
+ */
31
+ maxClusterSize?: number;
32
+ }
33
+ /**
34
+ * it use the chemical shifts and the coupling between them in order to generate a FID.
35
+ * It does not propagate the hamiltonian of the spin system, instead it simulate all the
36
+ * frequencies in the spectrum (including second order) and add all the waves in a real and
37
+ * imaginary parts, that is why the couplings should be assigned in order to generate the spin system.
38
+ */
39
+ export declare function signalsToFID(signals: NMRSignal1D[], options: SignalsToFIDOptions): {
40
+ re: import("cheminfo-types").DoubleArray;
41
+ im: import("cheminfo-types").DoubleArray;
42
+ };
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.signalsToFID = void 0;
4
+ const ml_spectra_processing_1 = require("ml-spectra-processing");
5
+ const apodization_1 = require("../apodization/apodization");
6
+ const signalsToSpinSystem_1 = require("./simulation/signalsToSpinSystem");
7
+ const simulateXYPeaks_1 = require("./simulation/simulateXYPeaks");
8
+ const splitSpinSystem_1 = require("./simulation/splitSpinSystem");
9
+ const twoPi = Math.PI * 2;
10
+ /**
11
+ * it use the chemical shifts and the coupling between them in order to generate a FID.
12
+ * It does not propagate the hamiltonian of the spin system, instead it simulate all the
13
+ * frequencies in the spectrum (including second order) and add all the waves in a real and
14
+ * imaginary parts, that is why the couplings should be assigned in order to generate the spin system.
15
+ */
16
+ function signalsToFID(signals, options) {
17
+ const { lb = 1, from = 0, to = 10, nbPoints = 1024, frequency = 400, maxClusterSize = 8, } = options;
18
+ let spinSystem = (0, signalsToSpinSystem_1.signalsToSpinSystem)(signals);
19
+ spinSystem.clusters = (0, splitSpinSystem_1.splitSpinSystem)(spinSystem, {
20
+ frequency,
21
+ maxClusterSize,
22
+ });
23
+ const peaks = (0, simulateXYPeaks_1.simulateXYPeaks)(spinSystem, { frequency });
24
+ const re = new Float64Array(nbPoints);
25
+ const im = new Float64Array(nbPoints);
26
+ const sw = Math.abs(to - from);
27
+ const adquisitionTime = nbPoints / (sw * frequency);
28
+ const time = (0, ml_spectra_processing_1.xSequentialFill)({
29
+ size: nbPoints,
30
+ from: 0,
31
+ to: adquisitionTime,
32
+ });
33
+ for (const peak of peaks) {
34
+ const { x, y } = peak;
35
+ const cs = x * frequency * twoPi;
36
+ for (let i = 0; i < nbPoints; i++) {
37
+ re[i] += y * Math.cos(cs * time[i]);
38
+ im[i] += y * Math.sin(cs * time[i]);
39
+ }
40
+ }
41
+ const { windowData, ...result } = (0, apodization_1.apodization)({ re, im }, {
42
+ pointsToShift: 0,
43
+ compose: {
44
+ length: nbPoints,
45
+ shapes: [
46
+ {
47
+ start: 0,
48
+ shape: {
49
+ kind: 'exponential',
50
+ options: {
51
+ dw: adquisitionTime / (nbPoints - 1),
52
+ lb,
53
+ },
54
+ },
55
+ },
56
+ ],
57
+ },
58
+ });
59
+ return result;
60
+ }
61
+ exports.signalsToFID = signalsToFID;
62
+ //# sourceMappingURL=signalsToFID.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signalsToFID.js","sourceRoot":"","sources":["../../src/signals/signalsToFID.ts"],"names":[],"mappings":";;;AAAA,iEAAwD;AAExD,4DAAyD;AAGzD,0EAAuE;AACvE,kEAA+D;AAC/D,kEAA+D;AAkC/D,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AAE1B;;;;;GAKG;AACH,SAAgB,YAAY,CAC1B,OAAsB,EACtB,OAA4B;IAE5B,MAAM,EACJ,EAAE,GAAG,CAAC,EACN,IAAI,GAAG,CAAC,EACR,EAAE,GAAG,EAAE,EACP,QAAQ,GAAG,IAAI,EACf,SAAS,GAAG,GAAG,EACf,cAAc,GAAG,CAAC,GACnB,GAAG,OAAO,CAAC;IAEZ,IAAI,UAAU,GAAG,IAAA,yCAAmB,EAAC,OAAO,CAAC,CAAC;IAE9C,UAAU,CAAC,QAAQ,GAAG,IAAA,iCAAe,EAAC,UAAU,EAAE;QAChD,SAAS;QACT,cAAc;KACf,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,IAAA,iCAAe,EAAC,UAAU,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IACzD,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,CAAC,CAAC;IAEtC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IAC/B,MAAM,eAAe,GAAG,QAAQ,GAAG,CAAC,EAAE,GAAG,SAAS,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,IAAA,uCAAe,EAAC;QAC3B,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,CAAC;QACP,EAAE,EAAE,eAAe;KACpB,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QACxB,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;QACtB,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,GAAG,KAAK,CAAC;QACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE;YACjC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACpC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;SACrC;KACF;IAED,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,GAAG,IAAA,yBAAW,EAC3C,EAAE,EAAE,EAAE,EAAE,EAAE,EACV;QACE,aAAa,EAAE,CAAC;QAChB,OAAO,EAAE;YACP,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE;gBACN;oBACE,KAAK,EAAE,CAAC;oBACR,KAAK,EAAE;wBACL,IAAI,EAAE,aAAa;wBACnB,OAAO,EAAE;4BACP,EAAE,EAAE,eAAe,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC;4BACpC,EAAE;yBACH;qBACF;iBACF;aACF;SACF;KACF,CACF,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AA/DD,oCA+DC"}
package/lib-esm/index.js CHANGED
@@ -20,6 +20,7 @@ export * from './signals/signalsToRanges';
20
20
  export * from './signals/signalsToXY';
21
21
  export * from './signals/signals2DToZ';
22
22
  export * from './signals/optimizeSignals';
23
+ export * from './signals/signalsToFID';
23
24
  export * from './utilities/resurrect';
24
25
  export * from './utilities/rangeFromSignal';
25
26
  export * from './utilities/getFrequency';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAE7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AAEjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAE/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAE5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AAEpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAE1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AAEzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AAEtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAE7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAE3C,cAAc,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAE7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AAEjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAE/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAE5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AAEpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AAEvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AAEzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AAEtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAE7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAE3C,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { xSequentialFill } from 'ml-spectra-processing';
2
+ import { apodization } from '../apodization/apodization';
3
+ import { signalsToSpinSystem } from './simulation/signalsToSpinSystem';
4
+ import { simulateXYPeaks } from './simulation/simulateXYPeaks';
5
+ import { splitSpinSystem } from './simulation/splitSpinSystem';
6
+ const twoPi = Math.PI * 2;
7
+ /**
8
+ * it use the chemical shifts and the coupling between them in order to generate a FID.
9
+ * It does not propagate the hamiltonian of the spin system, instead it simulate all the
10
+ * frequencies in the spectrum (including second order) and add all the waves in a real and
11
+ * imaginary parts, that is why the couplings should be assigned in order to generate the spin system.
12
+ */
13
+ export function signalsToFID(signals, options) {
14
+ const { lb = 1, from = 0, to = 10, nbPoints = 1024, frequency = 400, maxClusterSize = 8, } = options;
15
+ let spinSystem = signalsToSpinSystem(signals);
16
+ spinSystem.clusters = splitSpinSystem(spinSystem, {
17
+ frequency,
18
+ maxClusterSize,
19
+ });
20
+ const peaks = simulateXYPeaks(spinSystem, { frequency });
21
+ const re = new Float64Array(nbPoints);
22
+ const im = new Float64Array(nbPoints);
23
+ const sw = Math.abs(to - from);
24
+ const adquisitionTime = nbPoints / (sw * frequency);
25
+ const time = xSequentialFill({
26
+ size: nbPoints,
27
+ from: 0,
28
+ to: adquisitionTime,
29
+ });
30
+ for (const peak of peaks) {
31
+ const { x, y } = peak;
32
+ const cs = x * frequency * twoPi;
33
+ for (let i = 0; i < nbPoints; i++) {
34
+ re[i] += y * Math.cos(cs * time[i]);
35
+ im[i] += y * Math.sin(cs * time[i]);
36
+ }
37
+ }
38
+ const { windowData, ...result } = apodization({ re, im }, {
39
+ pointsToShift: 0,
40
+ compose: {
41
+ length: nbPoints,
42
+ shapes: [
43
+ {
44
+ start: 0,
45
+ shape: {
46
+ kind: 'exponential',
47
+ options: {
48
+ dw: adquisitionTime / (nbPoints - 1),
49
+ lb,
50
+ },
51
+ },
52
+ },
53
+ ],
54
+ },
55
+ });
56
+ return result;
57
+ }
58
+ //# sourceMappingURL=signalsToFID.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signalsToFID.js","sourceRoot":"","sources":["../../src/signals/signalsToFID.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAkC/D,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AAE1B;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAsB,EACtB,OAA4B;IAE5B,MAAM,EACJ,EAAE,GAAG,CAAC,EACN,IAAI,GAAG,CAAC,EACR,EAAE,GAAG,EAAE,EACP,QAAQ,GAAG,IAAI,EACf,SAAS,GAAG,GAAG,EACf,cAAc,GAAG,CAAC,GACnB,GAAG,OAAO,CAAC;IAEZ,IAAI,UAAU,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAE9C,UAAU,CAAC,QAAQ,GAAG,eAAe,CAAC,UAAU,EAAE;QAChD,SAAS;QACT,cAAc;KACf,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,eAAe,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IACzD,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,CAAC,CAAC;IAEtC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IAC/B,MAAM,eAAe,GAAG,QAAQ,GAAG,CAAC,EAAE,GAAG,SAAS,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,eAAe,CAAC;QAC3B,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,CAAC;QACP,EAAE,EAAE,eAAe;KACpB,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QACxB,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;QACtB,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,GAAG,KAAK,CAAC;QACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE;YACjC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACpC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;SACrC;KACF;IAED,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,GAAG,WAAW,CAC3C,EAAE,EAAE,EAAE,EAAE,EAAE,EACV;QACE,aAAa,EAAE,CAAC;QAChB,OAAO,EAAE;YACP,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE;gBACN;oBACE,KAAK,EAAE,CAAC;oBACR,KAAK,EAAE;wBACL,IAAI,EAAE,aAAa;wBACnB,OAAO,EAAE;4BACP,EAAE,EAAE,eAAe,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC;4BACpC,EAAE;yBACH;qBACF;iBACF;aACF;SACF;KACF,CACF,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nmr-processing",
3
- "version": "9.2.0",
3
+ "version": "9.3.0",
4
4
  "description": "Pure functions allowing to process NMR spectra.",
5
5
  "main": "./lib/index.js",
6
6
  "module": "./lib-esm/index.js",
@@ -38,20 +38,20 @@
38
38
  },
39
39
  "homepage": "https://github.com/cheminfo/nmr-processing#readme",
40
40
  "devDependencies": {
41
- "@types/jest": "^28.1.6",
41
+ "@types/jest": "^29.2.2",
42
42
  "cheminfo-build": "^1.1.11",
43
43
  "cheminfo-types": "^1.4.0",
44
- "eslint": "^8.22.0",
45
- "eslint-config-cheminfo-typescript": "^11.0.1",
46
- "jest": "^28.1.3",
44
+ "eslint": "^8.27.0",
45
+ "eslint-config-cheminfo-typescript": "^11.2.2",
46
+ "jest": "^29.3.1",
47
47
  "jest-matcher-deep-close-to": "^3.0.2",
48
48
  "md5": "^2.3.0",
49
49
  "nmr-xy-testdata": "^0.5.1",
50
- "openchemlib": "^8.0.0",
50
+ "openchemlib": "^8.0.1",
51
51
  "prettier": "^2.7.1",
52
52
  "rimraf": "^3.0.2",
53
- "ts-jest": "^28.0.8",
54
- "typescript": "^4.7.4"
53
+ "ts-jest": "^29.0.3",
54
+ "typescript": "^4.8.4"
55
55
  },
56
56
  "dependencies": {
57
57
  "@lukeed/uuid": "^2.0.0",
@@ -68,13 +68,13 @@
68
68
  "ml-gsd": "^12.1.2",
69
69
  "ml-hclust": "^3.1.0",
70
70
  "ml-levenberg-marquardt": "^4.1.0",
71
- "ml-matrix": "^6.10.2",
71
+ "ml-matrix": "^6.10.4",
72
72
  "ml-matrix-convolution": "^1.0.0",
73
73
  "ml-matrix-peaks-finder": "^1.0.0",
74
74
  "ml-peak-shape-generator": "^4.1.2",
75
75
  "ml-simple-clustering": "^0.1.0",
76
76
  "ml-sparse-matrix": "^2.1.0",
77
- "ml-spectra-processing": "^11.12.0",
77
+ "ml-spectra-processing": "^11.14.0",
78
78
  "ml-tree-set": "^0.1.1",
79
79
  "nmr-correlation": "^2.3.3",
80
80
  "openchemlib-utils": "^2.0.0",
package/src/index.ts CHANGED
@@ -25,6 +25,7 @@ export * from './signals/signalsToRanges';
25
25
  export * from './signals/signalsToXY';
26
26
  export * from './signals/signals2DToZ';
27
27
  export * from './signals/optimizeSignals';
28
+ export * from './signals/signalsToFID';
28
29
 
29
30
  export * from './utilities/resurrect';
30
31
  export * from './utilities/rangeFromSignal';
@@ -0,0 +1,113 @@
1
+ import { xSequentialFill } from 'ml-spectra-processing';
2
+
3
+ import { apodization } from '../apodization/apodization';
4
+
5
+ import { NMRSignal1D } from './NMRSignal1D';
6
+ import { signalsToSpinSystem } from './simulation/signalsToSpinSystem';
7
+ import { simulateXYPeaks } from './simulation/simulateXYPeaks';
8
+ import { splitSpinSystem } from './simulation/splitSpinSystem';
9
+
10
+ export interface SignalsToFIDOptions {
11
+ /**
12
+ * at the end of the superposition of all component, an exponential apodization will be applied
13
+ * in order to have FID like shape.
14
+ * @default 1
15
+ */
16
+ lb?: number;
17
+ /**
18
+ * lower limit of the spectrum
19
+ * @default 0
20
+ */
21
+ from?: number;
22
+ /**
23
+ * upper limit of the spectrum
24
+ * @default 10
25
+ */
26
+ to?: number;
27
+ /**
28
+ * number of points of the resulting FID
29
+ */
30
+ nbPoints?: number;
31
+ /**
32
+ * It is the frequency of the carrier (e.g. SFO1 for bruker spectrometers)
33
+ */
34
+ frequency?: number;
35
+ /**
36
+ * Maximum number of atoms on each cluster that can be considered to be simulated together.
37
+ * It affects the the quality and speed of the simulation.
38
+ */
39
+ maxClusterSize?: number;
40
+ }
41
+
42
+ const twoPi = Math.PI * 2;
43
+
44
+ /**
45
+ * it use the chemical shifts and the coupling between them in order to generate a FID.
46
+ * It does not propagate the hamiltonian of the spin system, instead it simulate all the
47
+ * frequencies in the spectrum (including second order) and add all the waves in a real and
48
+ * imaginary parts, that is why the couplings should be assigned in order to generate the spin system.
49
+ */
50
+ export function signalsToFID(
51
+ signals: NMRSignal1D[],
52
+ options: SignalsToFIDOptions,
53
+ ) {
54
+ const {
55
+ lb = 1,
56
+ from = 0,
57
+ to = 10,
58
+ nbPoints = 1024,
59
+ frequency = 400,
60
+ maxClusterSize = 8,
61
+ } = options;
62
+
63
+ let spinSystem = signalsToSpinSystem(signals);
64
+
65
+ spinSystem.clusters = splitSpinSystem(spinSystem, {
66
+ frequency,
67
+ maxClusterSize,
68
+ });
69
+
70
+ const peaks = simulateXYPeaks(spinSystem, { frequency });
71
+ const re = new Float64Array(nbPoints);
72
+ const im = new Float64Array(nbPoints);
73
+
74
+ const sw = Math.abs(to - from);
75
+ const adquisitionTime = nbPoints / (sw * frequency);
76
+ const time = xSequentialFill({
77
+ size: nbPoints,
78
+ from: 0,
79
+ to: adquisitionTime,
80
+ });
81
+
82
+ for (const peak of peaks) {
83
+ const { x, y } = peak;
84
+ const cs = x * frequency * twoPi;
85
+ for (let i = 0; i < nbPoints; i++) {
86
+ re[i] += y * Math.cos(cs * time[i]);
87
+ im[i] += y * Math.sin(cs * time[i]);
88
+ }
89
+ }
90
+
91
+ const { windowData, ...result } = apodization(
92
+ { re, im },
93
+ {
94
+ pointsToShift: 0,
95
+ compose: {
96
+ length: nbPoints,
97
+ shapes: [
98
+ {
99
+ start: 0,
100
+ shape: {
101
+ kind: 'exponential',
102
+ options: {
103
+ dw: adquisitionTime / (nbPoints - 1),
104
+ lb,
105
+ },
106
+ },
107
+ },
108
+ ],
109
+ },
110
+ },
111
+ );
112
+ return result;
113
+ }