diff --git a/src/__tests__/__snapshots__/index.test.ts.snap b/src/__tests__/__snapshots__/index.test.ts.snap index f7943417..8f5f5a80 100644 --- a/src/__tests__/__snapshots__/index.test.ts.snap +++ b/src/__tests__/__snapshots__/index.test.ts.snap @@ -111,9 +111,9 @@ exports[`test existence of exported functions 1`] = ` "xreimSortX", "xreimZeroFilling", "xyArrayAlign", + "xyArrayAlignToFirst", "xyArrayMerge", "xyArrayWeightedMerge", - "xyArrayAlignToFirst", "xyObjectBestPoints", "xyObjectJoinX", "xyObjectMaxXPoint", diff --git a/src/xy2/__tests__/xy2ToXY.test.ts b/src/xy2/__tests__/xy2ToXY.test.ts index 04e93f5c..e72a0b7a 100644 --- a/src/xy2/__tests__/xy2ToXY.test.ts +++ b/src/xy2/__tests__/xy2ToXY.test.ts @@ -1,4 +1,4 @@ -import { xy2ToXY } from '../../index'; +import { xy2ToXY } from '../xy2ToXY'; test('xy2ToXY', () => { expect( diff --git a/src/xyArray/__tests__/xyArrayAlign.test.ts b/src/xyArray/__tests__/xyArrayAlign.test.ts index 97b48465..aaf4d657 100644 --- a/src/xyArray/__tests__/xyArrayAlign.test.ts +++ b/src/xyArray/__tests__/xyArrayAlign.test.ts @@ -1,41 +1,33 @@ -import { xyArrayAlign } from '../../index'; +import { xyArrayAlign } from '../xyArrayAlign'; -describe('xyArrayAlign', () => { - it('same length spectra, simple integers', () => { - const data = [ - { x: [1, 2, 3], y: [1, 1, 1] }, - { x: [0.1, 1.1, 2.1, 3.1, 4.1], y: [1, 1, 1, 1, 1] }, - { x: [2.9, 3.1, 3.9, 4.9], y: [1, 1, 1, 1] }, - ]; - const result = xyArrayAlign(data, { delta: 0.15 }); +test('same length spectra, simple integers', () => { + const data = [ + { x: [1, 2, 3], y: [1, 1, 1] }, + { x: [0.1, 1.1, 2.1, 3.1, 4.1], y: [1, 1, 1, 1, 1] }, + { x: [2.9, 3.1, 3.9, 4.9], y: [1, 1, 1, 1] }, + ]; + const result = xyArrayAlign(data, { delta: 0.15 }); - result.x = Array.from(result.x); - result.ys = result.ys.map((array) => Array.from(array)); - - expect(result).toStrictEqual({ - x: [0.1, 1.05, 2.05, 3.025, 3.9, 4.1, 4.9], - ys: [ - [0, 1, 1, 1, 0, 0, 0], - [1, 1, 1, 1, 0, 1, 0], - [0, 0, 0, 2, 1, 0, 1], - ], - }); + expect(result).toStrictEqual({ + x: Float64Array.from([0.1, 1.05, 2.05, 3.025, 3.9, 4.1, 4.9]), + ys: [ + Float64Array.from([0, 1, 1, 1, 0, 0, 0]), + Float64Array.from([1, 1, 1, 1, 0, 1, 0]), + Float64Array.from([0, 0, 0, 2, 1, 0, 1]), + ], }); +}); - it('The y values must be present everywhere', () => { - const data = [ - { x: [1, 2, 3], y: [1, 1, 1] }, - { x: [0.1, 1.1, 2.1, 3.1, 4.1], y: [1, 1, 1, 1, 1] }, - { x: [2.9, 3.1, 3.9, 4.9], y: [1, 1, 1, 1] }, - ]; - const result = xyArrayAlign(data, { delta: 0.15, requiredY: true }); - - result.x = Array.from(result.x); - result.ys = result.ys.map((array) => Array.from(array)); +test('The y values must be present everywhere', () => { + const data = [ + { x: [1, 2, 3], y: [1, 1, 1] }, + { x: [0.1, 1.1, 2.1, 3.1, 4.1], y: [1, 1, 1, 1, 1] }, + { x: [2.9, 3.1, 3.9, 4.9], y: [1, 1, 1, 1] }, + ]; + const result = xyArrayAlign(data, { delta: 0.15, requiredY: true }); - expect(result).toStrictEqual({ - x: [3.025], - ys: [[1], [1], [2]], - }); + expect(result).toStrictEqual({ + x: [3.025], + ys: [[1], [1], [2]], }); }); diff --git a/src/xyArray/__tests__/xyArrayAlignToFirst.test.ts b/src/xyArray/__tests__/xyArrayAlignToFirst.test.ts index a89babfb..ad7e5cb6 100644 --- a/src/xyArray/__tests__/xyArrayAlignToFirst.test.ts +++ b/src/xyArray/__tests__/xyArrayAlignToFirst.test.ts @@ -1,41 +1,35 @@ -import { xyArrayAlignToFirst } from '../../index'; +import { xyArrayAlignToFirst } from '../xyArrayAlignToFirst'; -describe('xyArrayAlignToFirst', () => { - it('mixed example with delta: 0.25', () => { - const data = [ - { x: [1, 1.1, 2, 4], y: [1, 1, 1, 1] }, - { x: [0.1, 0.95, 1.05, 3], y: [1, 1, 1, 1] }, - { x: [2.05, 3.9, 4.1, 4.9, 5.1], y: [1, 1, 1, 1, 3] }, - ]; - const result = xyArrayAlignToFirst(data, { delta: 0.25 }); - result.x = Array.from(result.x); - result.ys = result.ys.map((array) => Array.from(array)); - expect(result).toStrictEqual({ - x: [0.1, 1, 1.1, 2, 3, 4, 5.05], - ys: [ - [0, 1, 1, 1, 0, 1, 0], - [1, 1, 1, 0, 1, 0, 0], - [0, 0, 0, 1, 0, 2, 4], - ], - }); +test('mixed example with delta: 0.25', () => { + const data = [ + { x: [1, 1.1, 2, 4], y: [1, 1, 1, 1] }, + { x: [0.1, 0.95, 1.05, 3], y: [1, 1, 1, 1] }, + { x: [2.05, 3.9, 4.1, 4.9, 5.1], y: [1, 1, 1, 1, 3] }, + ]; + const result = xyArrayAlignToFirst(data, { delta: 0.25 }); + expect(result).toStrictEqual({ + x: Float64Array.from([0.1, 1, 1.1, 2, 3, 4, 5.05]), + ys: [ + Float64Array.from([0, 1, 1, 1, 0, 1, 0]), + Float64Array.from([1, 1, 1, 0, 1, 0, 0]), + Float64Array.from([0, 0, 0, 1, 0, 2, 4]), + ], }); +}); - it('mixed example with delta a callback', () => { - const data = [ - { x: [1, 1.1, 2, 4], y: [1, 1, 1, 1] }, - { x: [0.1, 0.95, 1.05, 3], y: [1, 1, 1, 1] }, - { x: [2.05, 3.9, 4.1, 4.9, 5.1], y: [1, 1, 1, 1, 3] }, - ]; - const result = xyArrayAlignToFirst(data, { delta: () => 0.25 }); - result.x = Array.from(result.x); - result.ys = result.ys.map((array) => Array.from(array)); - expect(result).toStrictEqual({ - x: [0.1, 1, 1.1, 2, 3, 4, 5.05], - ys: [ - [0, 1, 1, 1, 0, 1, 0], - [1, 1, 1, 0, 1, 0, 0], - [0, 0, 0, 1, 0, 2, 4], - ], - }); +test('mixed example with delta a callback', () => { + const data = [ + { x: [1, 1.1, 2, 4], y: [1, 1, 1, 1] }, + { x: [0.1, 0.95, 1.05, 3], y: [1, 1, 1, 1] }, + { x: [2.05, 3.9, 4.1, 4.9, 5.1], y: [1, 1, 1, 1, 3] }, + ]; + const result = xyArrayAlignToFirst(data, { delta: () => 0.25 }); + expect(result).toStrictEqual({ + x: Float64Array.from([0.1, 1, 1.1, 2, 3, 4, 5.05]), + ys: [ + Float64Array.from([0, 1, 1, 1, 0, 1, 0]), + Float64Array.from([1, 1, 1, 0, 1, 0, 0]), + Float64Array.from([0, 0, 0, 1, 0, 2, 4]), + ], }); }); diff --git a/src/xyArray/__tests__/xyArrayMerge.test.ts b/src/xyArray/__tests__/xyArrayMerge.test.ts index 01215f62..9f0c90e8 100644 --- a/src/xyArray/__tests__/xyArrayMerge.test.ts +++ b/src/xyArray/__tests__/xyArrayMerge.test.ts @@ -1,20 +1,15 @@ -import { xyArrayMerge } from '../../index'; +import { xyArrayMerge } from '../xyArrayMerge'; -describe('xyArrayMerge', () => { - it('same length spectra, simple integers', () => { - const data = [ - { x: [1, 2, 3], y: [1, 1, 1] }, - { x: [0.1, 1.1, 2.1, 3.1, 4.1], y: [1, 1, 1, 1, 1] }, - { x: [2.9, 3.1, 3.9, 4.9], y: [1, 1, 1, 1] }, - ]; - const result = xyArrayMerge(data, { delta: 0.15 }); +test('same length spectra, simple integers', () => { + const data = [ + { x: [1, 2, 3], y: [1, 1, 1] }, + { x: [0.1, 1.1, 2.1, 3.1, 4.1], y: [1, 1, 1, 1, 1] }, + { x: [2.9, 3.1, 3.9, 4.9], y: [1, 1, 1, 1] }, + ]; + const result = xyArrayMerge(data, { delta: 0.15 }); - result.x = Array.from(result.x); - result.y = Array.from(result.y); - - expect(result).toStrictEqual({ - x: [0.1, 1.05, 2.05, 3.025, 3.9, 4.1, 4.9], - y: [1, 2, 2, 4, 1, 1, 1], - }); + expect(result).toStrictEqual({ + x: Float64Array.from([0.1, 1.05, 2.05, 3.025, 3.9, 4.1, 4.9]), + y: Float64Array.from([1, 2, 2, 4, 1, 1, 1]), }); }); diff --git a/src/xyArray/__tests__/xyArrayWeightedMerge.test.ts b/src/xyArray/__tests__/xyArrayWeightedMerge.test.ts index dde5cfba..b73459c1 100644 --- a/src/xyArray/__tests__/xyArrayWeightedMerge.test.ts +++ b/src/xyArray/__tests__/xyArrayWeightedMerge.test.ts @@ -1,107 +1,105 @@ import { DataXY } from 'cheminfo-types'; import XSAdd from 'ml-xsadd'; -import { xyArrayWeightedMerge } from '../../index'; +import { xyArrayWeightedMerge } from '../xyArrayWeightedMerge'; -describe('xyArrayWeightedMerge', () => { - it('2 slots', () => { - const data = [ - { x: [100, 202, 300], y: [10, 30, 20] }, - { x: [101, 201, 400], y: [30, 10, 40] }, - ]; - const result = xyArrayWeightedMerge(data, { delta: 2 }); +test('2 slots', () => { + const data = [ + { x: [100, 202, 300], y: [10, 30, 20] }, + { x: [101, 201, 400], y: [30, 10, 40] }, + ]; + const result = xyArrayWeightedMerge(data, { delta: 2 }); - expect(result).toStrictEqual({ - x: [100.75, 201.75, 300, 400], - y: [40, 40, 20, 40], - }); + expect(result).toStrictEqual({ + x: [100.75, 201.75, 300, 400], + y: [40, 40, 20, 40], }); +}); - it('simple no merge', () => { - const data = [ - { x: [10, 20], y: [1, 2] }, - { x: [60, 70], y: [6, 7] }, - { x: [30, 40], y: [3, 4] }, - { x: [50, 80], y: [5, 8] }, - ]; - const result = xyArrayWeightedMerge(data, { delta: 2 }); - expect(result).toStrictEqual({ - x: [10, 20, 30, 40, 50, 60, 70, 80], - y: [1, 2, 3, 4, 5, 6, 7, 8], - }); +test('simple no merge', () => { + const data = [ + { x: [10, 20], y: [1, 2] }, + { x: [60, 70], y: [6, 7] }, + { x: [30, 40], y: [3, 4] }, + { x: [50, 80], y: [5, 8] }, + ]; + const result = xyArrayWeightedMerge(data, { delta: 2 }); + expect(result).toStrictEqual({ + x: [10, 20, 30, 40, 50, 60, 70, 80], + y: [1, 2, 3, 4, 5, 6, 7, 8], }); +}); - it('simple full merge', () => { - const data = [ - { x: [1, 2], y: [1, 2] }, - { x: [6, 7], y: [6, 7] }, - { x: [3, 4], y: [3, 4] }, - { x: [5, 8], y: [5, 8] }, - ]; - const result = xyArrayWeightedMerge(data); - expect(result).toMatchCloseTo({ x: [5.666666666666667], y: [36] }); - }); +test('simple full merge', () => { + const data = [ + { x: [1, 2], y: [1, 2] }, + { x: [6, 7], y: [6, 7] }, + { x: [3, 4], y: [3, 4] }, + { x: [5, 8], y: [5, 8] }, + ]; + const result = xyArrayWeightedMerge(data); + expect(result).toMatchCloseTo({ x: [5.666666666666667], y: [36] }); +}); - it('check dense weighted average for x', () => { - const data = [ - { x: [100, 101, 102, 200, 201, 202], y: [10, 20, 30, 40, 50, 60] }, - { x: [101, 102, 103, 300], y: [30, 10, 40, 50] }, - ]; - const result = xyArrayWeightedMerge(data, { delta: 2 }); +test('check dense weighted average for x', () => { + const data = [ + { x: [100, 101, 102, 200, 201, 202], y: [10, 20, 30, 40, 50, 60] }, + { x: [101, 102, 103, 300], y: [30, 10, 40, 50] }, + ]; + const result = xyArrayWeightedMerge(data, { delta: 2 }); - expect(result).toMatchCloseTo({ - x: [101.78571428571429, 201.13333333333333, 300], - y: [140, 150, 50], - }); + expect(result).toMatchCloseTo({ + x: [101.78571428571429, 201.13333333333333, 300], + y: [140, 150, 50], }); +}); - it('large slot', () => { - const data = [ - { x: [100, 101, 102, 200, 201, 202], y: [10, 20, 30, 40, 50, 60] }, - { x: [101, 102, 103, 300], y: [30, 10, 40, 50] }, - ]; - const result = xyArrayWeightedMerge(data, { delta: 100 }); - expect(result).toMatchCloseTo({ x: [174.76470588235293], y: [340] }); - }); +test('large slot', () => { + const data = [ + { x: [100, 101, 102, 200, 201, 202], y: [10, 20, 30, 40, 50, 60] }, + { x: [101, 102, 103, 300], y: [30, 10, 40, 50] }, + ]; + const result = xyArrayWeightedMerge(data, { delta: 100 }); + expect(result).toMatchCloseTo({ x: [174.76470588235293], y: [340] }); +}); - it('function merge', () => { - const data = [ - { x: [100, 101, 102, 200, 201, 202], y: [10, 20, 30, 40, 50, 60] }, - { x: [101, 102, 103, 300], y: [30, 10, 40, 50] }, - ]; - const result = xyArrayWeightedMerge(data, { delta: (x) => x * x }); - expect(result).toMatchCloseTo({ x: [174.76470588235293], y: [340] }); - }); +test('function merge', () => { + const data = [ + { x: [100, 101, 102, 200, 201, 202], y: [10, 20, 30, 40, 50, 60] }, + { x: [101, 102, 103, 300], y: [30, 10, 40, 50] }, + ]; + const result = xyArrayWeightedMerge(data, { delta: (x) => x * x }); + expect(result).toMatchCloseTo({ x: [174.76470588235293], y: [340] }); +}); - it('empty data', () => { - const data: DataXY[] = []; - const result = xyArrayWeightedMerge(data, { delta: 2 }); - expect(result).toMatchCloseTo({ x: [], y: [] }); - }); +test('empty data', () => { + const data: DataXY[] = []; + const result = xyArrayWeightedMerge(data, { delta: 2 }); + expect(result).toMatchCloseTo({ x: [], y: [] }); +}); - it('large Data Set', () => { - const data = []; - const arraySize = 1e5; - const generator = new XSAdd(0); - for (let dataset = 0; dataset < 20; dataset++) { - const datum = { - x: new Float64Array(arraySize), - y: new Float64Array(arraySize), - }; - data.push(datum); - for (let i = 0; i < arraySize; i++) { - datum.x[i] = - Math.round(generator.random() * 100) * 10 + generator.random(); - datum.y[i] = generator.random(); - } - datum.x.sort(); - datum.y.sort(); +test('large Data Set', () => { + const data = []; + const arraySize = 1e5; + const generator = new XSAdd(0); + for (let dataset = 0; dataset < 20; dataset++) { + const datum = { + x: new Float64Array(arraySize), + y: new Float64Array(arraySize), + }; + data.push(datum); + for (let i = 0; i < arraySize; i++) { + datum.x[i] = + Math.round(generator.random() * 100) * 10 + generator.random(); + datum.y[i] = generator.random(); } - const start = Date.now(); - const result = xyArrayWeightedMerge(data, { delta: 2 }); - expect(result.x).toHaveLength(101); - expect(result.y).toHaveLength(101); - const elapsed = Date.now() - start; - expect(elapsed).toBeLessThanOrEqual(5000); - }); + datum.x.sort(); + datum.y.sort(); + } + const start = Date.now(); + const result = xyArrayWeightedMerge(data, { delta: 2 }); + expect(result.x).toHaveLength(101); + expect(result.y).toHaveLength(101); + const elapsed = Date.now() - start; + expect(elapsed).toBeLessThanOrEqual(5000); }); diff --git a/src/xyArray/index.ts b/src/xyArray/index.ts index 7b386867..d76b708a 100644 --- a/src/xyArray/index.ts +++ b/src/xyArray/index.ts @@ -1,4 +1,4 @@ export * from './xyArrayAlign'; +export * from './xyArrayAlignToFirst'; export * from './xyArrayMerge'; export * from './xyArrayWeightedMerge'; -export * from './xyArrayAlignToFirst'; diff --git a/src/xyArray/utils/getSlots.ts b/src/xyArray/utils/getSlots.ts index 31c9ef92..51a3e828 100644 --- a/src/xyArray/utils/getSlots.ts +++ b/src/xyArray/utils/getSlots.ts @@ -1,5 +1,21 @@ import { DataXY } from 'cheminfo-types'; +export interface GetSlotsOptions { + /** + * The range in which the two x values of the data/spectra must be to be placed on the same line. It may also be a function that allows to change `delta` depending on the X values of the spectrum + * @default 1 + */ + delta?: ((arg: number) => number) | number; +} + +export interface Slot { + from: number; + to: number; + average: number; + sum: number; + number: number; +} + /** * GetSlots. * @@ -8,45 +24,27 @@ import { DataXY } from 'cheminfo-types'; */ export function getSlots( data: DataXY[], - options: { - /** - * The range in which the two x values of the data/spectra must be to be placed on the same line. It may also be a function that allows to change `delta` depending on the X values of the spectrum - * @default 1 - */ - delta?: ((arg: number) => number) | number; - } = {}, -): Array<{ - from: number; - to: number; - average: number; - sum: number; - number: number; -}> { + options: GetSlotsOptions = {}, +): Slot[] { const { delta = 1 } = options; const deltaIsFunction = typeof delta === 'function'; const possibleXs = Float64Array.from( - ([] as number[]).concat(...data.map((spectrum) => spectrum.x as number[])), + data.map((spectrum) => spectrum.x as number[]).flat(), ).sort(); if (possibleXs.length === 0) { - throw new Error('xyArrayMerge can not process empty arrays'); + throw new Error('can not process empty arrays'); } - let currentSlot = { + let currentSlot: Slot = { from: possibleXs[0], to: possibleXs[0], average: possibleXs[0], sum: possibleXs[0], number: 1, }; - const slots: Array<{ - from: number; - to: number; - average: number; - sum: number; - number: number; - }> = [currentSlot]; + const slots: Slot[] = [currentSlot]; for (let i = 1; i < possibleXs.length; i++) { const currentDelta = deltaIsFunction ? delta(possibleXs[i]) : delta; if (possibleXs[i] - currentSlot.to <= currentDelta) { diff --git a/src/xyArray/utils/getSlotsToFirst.ts b/src/xyArray/utils/getSlotsToFirst.ts index c459032f..c009b706 100644 --- a/src/xyArray/utils/getSlotsToFirst.ts +++ b/src/xyArray/utils/getSlotsToFirst.ts @@ -1,6 +1,21 @@ import { DataXY } from 'cheminfo-types'; import { xyArrayWeightedMerge } from '../xyArrayWeightedMerge'; + +export interface GetSlotsToFirstOptions { + /** + * The range in which the two x values of the data/spectra must be to be placed on the same line. It may also be a function that allows to change `delta` depending on the X values of the spectrum + * @default 1 + */ + delta?: ((arg: number) => number) | number; +} + +export interface Slot { + from: number; + to: number; + value: number; +} + /** * GetSlotsToFirst. * @@ -9,19 +24,13 @@ import { xyArrayWeightedMerge } from '../xyArrayWeightedMerge'; */ export function getSlotsToFirst( data: DataXY[], - options: { - /** - * The range in which the two x values of the data/spectra must be to be placed on the same line. It may also be a function that allows to change `delta` depending on the X values of the spectrum - * @default 1 - */ - delta?: ((arg: number) => number) | number; - } = {}, -): Array<{ from: number; to: number; value: number }> { + options: GetSlotsToFirstOptions = {}, +): Slot[] { const { delta = 1 } = options; const deltaIsFunction = typeof delta === 'function'; const firstXs = data[0].x; - const slots: Array<{ from: number; to: number; value: number }> = []; + const slots: Slot[] = []; // we first create the slots based on the first spectrum for (const element of firstXs) { const currentDelta = deltaIsFunction ? delta(element) : delta; diff --git a/src/xyArray/xyArrayAlign.ts b/src/xyArray/xyArrayAlign.ts index 883c44a1..90a9ce02 100644 --- a/src/xyArray/xyArrayAlign.ts +++ b/src/xyArray/xyArrayAlign.ts @@ -1,9 +1,22 @@ import { DoubleArray, DataXY } from 'cheminfo-types'; -import { xyJoinX } from '../xy/xyJoinX'; +import { xyJoinX } from '../xy'; import { getSlots } from './utils/getSlots'; +export interface XYArrayAlignOptions { + /** + * The range in which the two x values of the data/spectra must be to be placed on the same line. It may also be a function that allows to change `delta` depending on the X values of the spectrum + * @default 1 + */ + delta?: ((arg: number) => number) | number; + /** + * If true, the y values must be present everywhere + * @default false + */ + requiredY?: boolean; +} + /** * Aligns data, can be used for spectra * @@ -12,18 +25,7 @@ import { getSlots } from './utils/getSlots'; */ export function xyArrayAlign( data: DataXY[], - options: { - /** - * The range in which the two x values of the data/spectra must be to be placed on the same line. It may also be a function that allows to change `delta` depending on the X values of the spectrum - * @default 1 - */ - delta?: ((arg: number) => number) | number; - /** - * If true, the y values must be present everywhere - * @default false - */ - requiredY?: boolean; - } = {}, + options: XYArrayAlignOptions = {}, ): { x: DoubleArray; ys: DoubleArray[]; @@ -32,7 +34,7 @@ export function xyArrayAlign( data = data.map((spectrum) => xyJoinX(spectrum, { delta })); - const slots = getSlots(data, options); + const slots = getSlots(data, { delta }); const x = Float64Array.from(slots.map((slot) => slot.average)); const ys = new Array(data.length) .fill(0) @@ -58,8 +60,8 @@ export function xyArrayAlign( return { x, ys }; } -function filterRequiredY(x: DoubleArray, ys: DoubleArray[]) { - const newX = []; +function filterRequiredY(x: Float64Array, ys: Float64Array[]) { + const newX: number[] = []; const newYs: number[][] = new Array(ys.length).fill(0).map(() => []); for (let i = 0; i < x.length; i++) { if (ys.every((y) => y[i] !== 0)) { diff --git a/src/xyArray/xyArrayAlignToFirst.ts b/src/xyArray/xyArrayAlignToFirst.ts index 7577f0a4..a291ef15 100644 --- a/src/xyArray/xyArrayAlignToFirst.ts +++ b/src/xyArray/xyArrayAlignToFirst.ts @@ -2,6 +2,14 @@ import { DoubleArray, DataXY } from 'cheminfo-types'; import { getSlotsToFirst } from './utils/getSlotsToFirst'; +export interface XYArrayAlignToFirstOptions { + /** + * The range in which the two x values of the data/spectra must be to be placed on the same line. It may also be a function that allows to change `delta` depending on the X values of the spectrum + * @default 1 + */ + delta?: ((arg: number) => number) | number; +} + /** * We align all the data/spectra to the first array of X. * The alignment is based on the X values of the first spectrum and the `delta` error allowed. @@ -12,18 +20,13 @@ import { getSlotsToFirst } from './utils/getSlotsToFirst'; */ export function xyArrayAlignToFirst( data: DataXY[], - options: { - /** - * The range in which the two x values of the data/spectra must be to be placed on the same line. It may also be a function that allows to change `delta` depending on the X values of the spectrum - * @default 1 - */ - delta?: ((arg: number) => number) | number; - } = {}, + options: XYArrayAlignToFirstOptions = {}, ): { x: DoubleArray; ys: DoubleArray[]; } { - const slots = getSlotsToFirst(data, options); + const { delta = 1 } = options; + const slots = getSlotsToFirst(data, { delta }); const x = Float64Array.from(slots.map((slot) => slot.value)); const ys = new Array(data.length) .fill(0) diff --git a/src/xyArray/xyArrayMerge.ts b/src/xyArray/xyArrayMerge.ts index 095a3635..597e34c6 100644 --- a/src/xyArray/xyArrayMerge.ts +++ b/src/xyArray/xyArrayMerge.ts @@ -1,8 +1,17 @@ import { DataXY } from 'cheminfo-types'; -import { xyJoinX } from '../xy/xyJoinX'; +import { xyJoinX } from '../xy'; import { getSlots } from './utils/getSlots'; + +export interface XYArrayMergeOptions { + /** + * The range in which the two x values of the data/spectra must be to be placed on the same line. It may also be a function that allows to change `delta` depending on the X values of the spectrum + * @default 1 + */ + delta?: ((arg: number) => number) | number; +} + /** * Merge DataXY * We have an array of DataXY and the goal is to merge all the values that are the closest possible @@ -12,20 +21,14 @@ import { getSlots } from './utils/getSlots'; */ export function xyArrayMerge( data: DataXY[], - options: { - /** - * The range in which the two x values of the data/spectra must be to be placed on the same line. It may also be a function that allows to change `delta` depending on the X values of the spectrum - * @default 1 - */ - delta?: ((arg: number) => number) | number; - } = {}, + options: XYArrayMergeOptions = {}, ): DataXY { const { delta = 1 } = options; - // we start by checking that the data/spectra don't have peaks too close and we simplify them + // We start by checking that the data/spectra don't have peaks too close and we simplify them. data = data.map((spectrum) => xyJoinX(spectrum, { delta })); - // at first we will calculate the X values (simple mean) - const slots = getSlots(data, options); + // At first, we will calculate the X values (simple mean). + const slots = getSlots(data, { delta }); const x = Float64Array.from(slots.map((slot) => slot.average)); const y = new Float64Array(x.length); diff --git a/src/xyArray/xyArrayWeightedMerge.ts b/src/xyArray/xyArrayWeightedMerge.ts index 959eb6b5..bba1013b 100644 --- a/src/xyArray/xyArrayWeightedMerge.ts +++ b/src/xyArray/xyArrayWeightedMerge.ts @@ -2,6 +2,14 @@ import { DataXY, NumberArray } from 'cheminfo-types'; import { Point } from '../types'; +export interface XYArrayWeightedMergeOptions { + /** + * The range in which the two x values of the data must be to be placed on the same line. It may also be a function that allows to change `delta` depending on the X values of the spectrum + * @default 1 + */ + delta?: ((arg: number) => number) | number; +} + /** * Merge DataXY * We have an array of DataXY and the goal is to merge all the values for which the deltaX is small or equal to delta. @@ -12,13 +20,7 @@ import { Point } from '../types'; */ export function xyArrayWeightedMerge( data: DataXY[], - options: { - /** - * The range in which the two x values of the data must be to be placed on the same line. It may also be a function that allows to change `delta` depending on the X values of the spectrum - * @default 1 - */ - delta?: ((arg: number) => number) | number; - } = {}, + options: XYArrayWeightedMergeOptions = {}, ): DataXY { let { delta = 1 } = options; if (typeof delta === 'number') {