spectrum-generator
Advanced tools
Comparing version 4.4.2 to 4.5.0
# Changelog | ||
## [4.5.0](https://www.github.com/cheminfo/spectrum-generator/compare/v4.4.2...v4.5.0) (2020-12-10) | ||
### Features | ||
* Improve speed by calculating point to point the peak shape. ([#24](https://www.github.com/cheminfo/spectrum-generator/issues/24)) ([b987289](https://www.github.com/cheminfo/spectrum-generator/commit/b987289b4b8aa9b44a81366ad68d29c3650e692b)) | ||
### [4.4.2](https://www.github.com/cheminfo/spectrum-generator/compare/v4.4.1...v4.4.2) (2020-12-04) | ||
@@ -4,0 +11,0 @@ |
@@ -5,5 +5,3 @@ 'use strict'; | ||
var normed = require('ml-array-normed'); | ||
var mlPeakShapeGenerator = require('ml-peak-shape-generator'); | ||
var objectHash = require('object-hash'); | ||
var d3Random = require('d3-random'); | ||
@@ -14,4 +12,2 @@ var XSAdd = require('ml-xsadd'); | ||
var normed__default = /*#__PURE__*/_interopDefaultLegacy(normed); | ||
var objectHash__default = /*#__PURE__*/_interopDefaultLegacy(objectHash); | ||
var XSAdd__default = /*#__PURE__*/_interopDefaultLegacy(XSAdd); | ||
@@ -69,5 +65,2 @@ | ||
let shapesCache = {}; | ||
const MAX_CACHE_LENGTH = 20; | ||
class SpectrumGenerator { | ||
@@ -84,6 +77,2 @@ constructor(options = {}) { | ||
kind: 'gaussian', | ||
options: { | ||
fwhm: 1000, | ||
length: 5001, | ||
}, | ||
}, | ||
@@ -93,2 +82,3 @@ }, | ||
); | ||
this.from = options.from; | ||
@@ -100,4 +90,6 @@ this.to = options.to; | ||
this.maxPeakHeight = Number.MIN_SAFE_INTEGER; | ||
this.shape = createShape(options.shape.kind, options.shape.options); | ||
let shapeGenerator = mlPeakShapeGenerator.getShapeGenerator(options.shape); | ||
this.shape = shapeGenerator; | ||
assertNumber(this.from, 'from'); | ||
@@ -178,4 +170,4 @@ assertNumber(this.to, 'to'); | ||
const shape = shapeOptions | ||
? createShape(shapeOptions.kind, shapeOptions.options) | ||
let shapeGenerator = shapeOptions | ||
? mlPeakShapeGenerator.getShapeGenerator(shapeOptions) | ||
: this.shape; | ||
@@ -186,5 +178,10 @@ | ||
const firstValue = xPosition - (widthLeft / 2) * shape.factor; | ||
const lastValue = xPosition + (widthRight / 2) * shape.factor; | ||
let factor = | ||
options.factor === undefined | ||
? shapeGenerator.getFactor() | ||
: options.factor; | ||
const firstValue = xPosition - (widthLeft / 2) * factor; | ||
const lastValue = xPosition + (widthRight / 2) * factor; | ||
const firstPoint = Math.max( | ||
@@ -202,19 +199,10 @@ 0, | ||
shapeGenerator.setFWHM(widthLeft); | ||
for (let index = firstPoint; index < Math.max(middlePoint, 0); index++) { | ||
let ratio = ((xPosition - this.data.x[index]) / widthLeft) * 2; | ||
this.data.y[index] += | ||
intensity * shapeGenerator.fct(this.data.x[index] - xPosition); | ||
} | ||
let shapeIndex = shape.halfLength - (ratio * shape.fwhm) / 2; | ||
let floorIndex = Math.floor(shapeIndex); | ||
let ceilIndex = Math.ceil(shapeIndex); | ||
let value = | ||
floorIndex === shapeIndex | ||
? shape.data[shapeIndex] | ||
: shape.data[floorIndex] * (ceilIndex - shapeIndex) + | ||
shape.data[ceilIndex] * (shapeIndex - floorIndex); | ||
shapeIndex = Math.round(shapeIndex); | ||
if (floorIndex >= 0 && ceilIndex < shape.data.length) { | ||
this.data.y[index] += value * intensity; | ||
} | ||
} | ||
// we calculate the right part of the gaussian | ||
shapeGenerator.setFWHM(widthRight); | ||
for ( | ||
@@ -225,16 +213,4 @@ let index = Math.min(middlePoint, lastPoint); | ||
) { | ||
let ratio = ((this.data.x[index] - xPosition) / widthRight) * 2; | ||
let shapeIndex = shape.halfLength - (ratio * shape.fwhm) / 2; | ||
let floorIndex = Math.floor(shapeIndex); | ||
let ceilIndex = Math.ceil(shapeIndex); | ||
let value = | ||
floorIndex === shapeIndex | ||
? shape.data[shapeIndex] | ||
: shape.data[floorIndex] * (ceilIndex - shapeIndex) + | ||
shape.data[ceilIndex] * (shapeIndex - floorIndex); | ||
shapeIndex = Math.round(shapeIndex); | ||
if (floorIndex >= 0 && ceilIndex <= shape.data.length) { | ||
this.data.y[index] += value * intensity; | ||
} | ||
this.data.y[index] += | ||
intensity * shapeGenerator.fct(this.data.x[index] - xPosition); | ||
} | ||
@@ -318,30 +294,3 @@ | ||
function createShape(kind, options) { | ||
const hash = objectHash__default['default']({ kind, options }); | ||
if (shapesCache[hash]) { | ||
return shapesCache[hash]; | ||
} | ||
let shape = {}; | ||
let newShape = mlPeakShapeGenerator.getShape(kind, options); | ||
shape.data = normed__default['default'](newShape.data, { | ||
algorithm: 'max', | ||
}); | ||
shape.fwhm = newShape.fwhm; | ||
shape.factor = (newShape.data.length - 1) / newShape.fwhm; | ||
shape.length = newShape.data.length; | ||
shape.halfLength = Math.floor(newShape.data.length / 2); | ||
if (Object.keys(shapesCache > MAX_CACHE_LENGTH)) { | ||
shapesCache = {}; | ||
} | ||
shapesCache[hash] = shape; | ||
return shape; | ||
} | ||
exports.SpectrumGenerator = SpectrumGenerator; | ||
exports.generateSpectrum = generateSpectrum; |
{ | ||
"name": "spectrum-generator", | ||
"version": "4.4.2", | ||
"version": "4.5.0", | ||
"description": "generate a spectrum from discrete peaks", | ||
@@ -43,24 +43,22 @@ "main": "lib/index.js", | ||
"@babel/plugin-transform-modules-commonjs": "^7.12.1", | ||
"@types/jest": "^26.0.15", | ||
"@types/jest": "^26.0.18", | ||
"cheminfo-build": "^1.1.8", | ||
"convert-to-jcamp": "^4.2.0", | ||
"eslint": "^7.13.0", | ||
"eslint": "^7.15.0", | ||
"eslint-config-cheminfo": "^5.2.2", | ||
"eslint-plugin-import": "^2.22.1", | ||
"eslint-plugin-jest": "^24.1.3", | ||
"eslint-plugin-prettier": "^3.1.4", | ||
"eslint-plugin-prettier": "^3.2.0", | ||
"esm": "^3.2.25", | ||
"jest": "^26.6.3", | ||
"ml-spectra-processing": "^4.8.0", | ||
"pnpm": "^5.13.1", | ||
"prettier": "^2.1.2", | ||
"rollup": "^2.33.3" | ||
"ml-spectra-processing": "^4.10.0", | ||
"pnpm": "^5.13.5", | ||
"prettier": "^2.2.1", | ||
"rollup": "^2.34.2" | ||
}, | ||
"dependencies": { | ||
"d3-random": "^2.2.2", | ||
"ml-array-normed": "^1.3.2", | ||
"ml-peak-shape-generator": "^0.10.2", | ||
"ml-xsadd": "2.0.0", | ||
"object-hash": "^2.0.3" | ||
"ml-peak-shape-generator": "^0.11.0", | ||
"ml-xsadd": "2.0.0" | ||
} | ||
} |
@@ -92,3 +92,3 @@ import { xyMaxYPoint } from 'ml-spectra-processing'; | ||
let max = xyMaxYPoint(spectrum); | ||
expect(spectrum.y[9]).toBeCloseTo(0.15749, 4); | ||
expect(spectrum.y[9]).toBeCloseTo(0.0625, 4); | ||
expect(max.x).toBe(10); | ||
@@ -95,0 +95,0 @@ expect(max.y).toBe(1); |
@@ -0,1 +1,2 @@ | ||
import { Lorentzian } from 'ml-peak-shape-generator'; | ||
import { xyMaxYPoint } from 'ml-spectra-processing'; | ||
@@ -39,4 +40,4 @@ | ||
const ys = spectrum.y; | ||
expect(ys[30]).toBe(10); | ||
expect(ys[70]).toBe(10); | ||
expect(ys[30]).toBeCloseTo(10 + 10 * Lorentzian.fct(3 - 7, 1), 7); | ||
expect(ys[70]).toBeCloseTo(10, 7); | ||
@@ -88,5 +89,5 @@ expect(ys[31] !== ys[71]).toBe(true); | ||
let max = xyMaxYPoint(spectrum); | ||
expect(spectrum.y[49]).toBeCloseTo(0.5, 10); | ||
expect(spectrum.y[49]).toBeCloseTo(0.5, 2); | ||
expect(max.x).toBe(2.5); | ||
expect(max.y).toBe(2); | ||
expect(max.y).toBeCloseTo(2, 3); | ||
}); | ||
@@ -140,6 +141,2 @@ | ||
kind: 'lorentzian', | ||
options: { | ||
length: 13, | ||
fwhm: 4, | ||
}, | ||
}, | ||
@@ -154,6 +151,2 @@ }, | ||
kind: 'gaussian', | ||
options: { | ||
length: 13, | ||
fwhm: 4, | ||
}, | ||
}, | ||
@@ -164,6 +157,6 @@ }, | ||
let max = xyMaxYPoint(spectrum); | ||
expect(spectrum.y[49]).toBeCloseTo(0.5, 10); | ||
expect(spectrum.y[49]).toBeCloseTo(0.5, 2); | ||
expect(max.x).toBe(2.5); | ||
expect(max.y).toBe(2); | ||
expect(max.y).toBeCloseTo(2, 2); | ||
}); | ||
}); |
@@ -0,1 +1,3 @@ | ||
import { Gaussian } from 'ml-peak-shape-generator'; | ||
import { SpectrumGenerator } from '..'; | ||
@@ -49,9 +51,13 @@ | ||
}); | ||
generator.addPeak([50, 100], { widthLeft: 10, widthRight: 30 }); | ||
generator.addPeak([50, 100], { widthLeft: 10, widthRight: 30, factor: 15 }); | ||
const spectrum = generator.getSpectrum(); | ||
const sumX = spectrum.x.reduce((previous, value) => previous + value); | ||
const sumY = spectrum.y.reduce((previous, value) => previous + value); | ||
expect(sumX).toBe(10050); | ||
expect(sumY).toBeCloseTo(4257.612789255516, 4); | ||
expect(sumY * generator.interval).toBeCloseTo( | ||
(Gaussian.getArea(10, { height: 100 }) + | ||
Gaussian.getArea(30, { height: 100 })) / | ||
2, | ||
0, | ||
); | ||
}); | ||
@@ -90,3 +96,3 @@ | ||
for (let i = 0; i < nPoints / 2; i++) { | ||
expect(spectrum.y[i]).toBe(spectrum.y[nPoints - 1 - i]); | ||
expect(spectrum.y[i]).toBeCloseTo(spectrum.y[nPoints - 1 - i], 7); | ||
expect(spectrum.y[i]).toBeLessThan(2); | ||
@@ -108,6 +114,6 @@ } | ||
expect(spectrum.y[0]).toBe(1); | ||
expect(spectrum.y[50 * 10]).toBe(12); | ||
expect(spectrum.y[100 * 10]).toBe(10); | ||
expect(spectrum.y[14 * 10]).toBe(2); | ||
expect(spectrum.y[0]).toBeCloseTo(1, 3); | ||
expect(spectrum.y[50 * 10]).toBeCloseTo(12, 3); | ||
expect(spectrum.y[100 * 10]).toBeCloseTo(10, 3); | ||
expect(spectrum.y[14 * 10]).toBeCloseTo(2, 3); | ||
}); | ||
@@ -127,6 +133,6 @@ | ||
expect(spectrum.y[0]).toBe(1); | ||
expect(spectrum.y[50 * 10]).toBe(12); | ||
expect(spectrum.y[100 * 10]).toBe(10); | ||
expect(spectrum.y[14 * 10]).toBe(2); | ||
expect(spectrum.y[0]).toBeCloseTo(1, 3); | ||
expect(spectrum.y[50 * 10]).toBeCloseTo(12, 3); | ||
expect(spectrum.y[100 * 10]).toBeCloseTo(10, 3); | ||
expect(spectrum.y[14 * 10]).toBeCloseTo(2, 3); | ||
}); | ||
@@ -142,7 +148,7 @@ | ||
const spectrum = generator.getSpectrum(); | ||
expect(spectrum.y[0]).toBe(1); | ||
expect(spectrum.y[50 * 10]).toBe(12); | ||
expect(spectrum.y[100 * 10]).toBe(10); | ||
expect(spectrum.y[14 * 10]).toBe(2); | ||
// console.log(spectrum) | ||
expect(spectrum.y[0]).toBeCloseTo(1, 3); | ||
expect(spectrum.y[50 * 10]).toBeCloseTo(12, 3); | ||
expect(spectrum.y[100 * 10]).toBeCloseTo(10, 3); | ||
expect(spectrum.y[14 * 10]).toBeCloseTo(2, 3); | ||
}); | ||
@@ -149,0 +155,0 @@ |
@@ -1,4 +0,2 @@ | ||
import normed from 'ml-array-normed'; | ||
import { getShape } from 'ml-peak-shape-generator'; | ||
import objectHash from 'object-hash'; | ||
import { getShapeGenerator } from 'ml-peak-shape-generator'; | ||
@@ -8,5 +6,2 @@ import addBaseline from './util/addBaseline.js'; | ||
let shapesCache = {}; | ||
const MAX_CACHE_LENGTH = 20; | ||
export class SpectrumGenerator { | ||
@@ -23,6 +18,2 @@ constructor(options = {}) { | ||
kind: 'gaussian', | ||
options: { | ||
fwhm: 1000, | ||
length: 5001, | ||
}, | ||
}, | ||
@@ -32,2 +23,3 @@ }, | ||
); | ||
this.from = options.from; | ||
@@ -39,4 +31,6 @@ this.to = options.to; | ||
this.maxPeakHeight = Number.MIN_SAFE_INTEGER; | ||
this.shape = createShape(options.shape.kind, options.shape.options); | ||
let shapeGenerator = getShapeGenerator(options.shape); | ||
this.shape = shapeGenerator; | ||
assertNumber(this.from, 'from'); | ||
@@ -117,4 +111,4 @@ assertNumber(this.to, 'to'); | ||
const shape = shapeOptions | ||
? createShape(shapeOptions.kind, shapeOptions.options) | ||
let shapeGenerator = shapeOptions | ||
? getShapeGenerator(shapeOptions) | ||
: this.shape; | ||
@@ -125,5 +119,10 @@ | ||
const firstValue = xPosition - (widthLeft / 2) * shape.factor; | ||
const lastValue = xPosition + (widthRight / 2) * shape.factor; | ||
let factor = | ||
options.factor === undefined | ||
? shapeGenerator.getFactor() | ||
: options.factor; | ||
const firstValue = xPosition - (widthLeft / 2) * factor; | ||
const lastValue = xPosition + (widthRight / 2) * factor; | ||
const firstPoint = Math.max( | ||
@@ -141,19 +140,10 @@ 0, | ||
shapeGenerator.setFWHM(widthLeft); | ||
for (let index = firstPoint; index < Math.max(middlePoint, 0); index++) { | ||
let ratio = ((xPosition - this.data.x[index]) / widthLeft) * 2; | ||
this.data.y[index] += | ||
intensity * shapeGenerator.fct(this.data.x[index] - xPosition); | ||
} | ||
let shapeIndex = shape.halfLength - (ratio * shape.fwhm) / 2; | ||
let floorIndex = Math.floor(shapeIndex); | ||
let ceilIndex = Math.ceil(shapeIndex); | ||
let value = | ||
floorIndex === shapeIndex | ||
? shape.data[shapeIndex] | ||
: shape.data[floorIndex] * (ceilIndex - shapeIndex) + | ||
shape.data[ceilIndex] * (shapeIndex - floorIndex); | ||
shapeIndex = Math.round(shapeIndex); | ||
if (floorIndex >= 0 && ceilIndex < shape.data.length) { | ||
this.data.y[index] += value * intensity; | ||
} | ||
} | ||
// we calculate the right part of the gaussian | ||
shapeGenerator.setFWHM(widthRight); | ||
for ( | ||
@@ -164,16 +154,4 @@ let index = Math.min(middlePoint, lastPoint); | ||
) { | ||
let ratio = ((this.data.x[index] - xPosition) / widthRight) * 2; | ||
let shapeIndex = shape.halfLength - (ratio * shape.fwhm) / 2; | ||
let floorIndex = Math.floor(shapeIndex); | ||
let ceilIndex = Math.ceil(shapeIndex); | ||
let value = | ||
floorIndex === shapeIndex | ||
? shape.data[shapeIndex] | ||
: shape.data[floorIndex] * (ceilIndex - shapeIndex) + | ||
shape.data[ceilIndex] * (shapeIndex - floorIndex); | ||
shapeIndex = Math.round(shapeIndex); | ||
if (floorIndex >= 0 && ceilIndex <= shape.data.length) { | ||
this.data.y[index] += value * intensity; | ||
} | ||
this.data.y[index] += | ||
intensity * shapeGenerator.fct(this.data.x[index] - xPosition); | ||
} | ||
@@ -256,28 +234,1 @@ | ||
} | ||
function createShape(kind, options) { | ||
const hash = objectHash({ kind, options }); | ||
if (shapesCache[hash]) { | ||
return shapesCache[hash]; | ||
} | ||
let shape = {}; | ||
let newShape = getShape(kind, options); | ||
shape.data = normed(newShape.data, { | ||
algorithm: 'max', | ||
}); | ||
shape.fwhm = newShape.fwhm; | ||
shape.factor = (newShape.data.length - 1) / newShape.fwhm; | ||
shape.length = newShape.data.length; | ||
shape.halfLength = Math.floor(newShape.data.length / 2); | ||
if (Object.keys(shapesCache > MAX_CACHE_LENGTH)) { | ||
shapesCache = {}; | ||
} | ||
shapesCache[hash] = shape; | ||
return shape; | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3
48046
1231
+ Addedcompute-array-constructors@1.0.1(transitive)
+ Addedcompute-array-dtype@1.0.1(transitive)
+ Addedcompute-dtype@1.0.0(transitive)
+ Addedcompute-erfinv@3.0.1(transitive)
+ Addedcompute-indexspace@1.0.1(transitive)
+ Addedcompute-polynomial@1.1.0(transitive)
+ Addedconst-max-uint32@1.0.2(transitive)
+ Addedconst-pinf-float64@1.0.0(transitive)
+ Addeddstructs-array-constructors@1.0.2(transitive)
+ Addeddstructs-array-dtype@1.0.2(transitive)
+ Addeddstructs-cast-arrays@1.0.3(transitive)
+ Addeddstructs-matrix@2.1.2(transitive)
+ Addedml-peak-shape-generator@0.11.0(transitive)
+ Addedobject-keys@1.1.1(transitive)
+ Addedregex-regex@1.0.0(transitive)
+ Addedtype-name@1.1.02.0.2(transitive)
+ Addedutils-copy@1.1.1(transitive)
+ Addedutils-copy-error@1.0.1(transitive)
+ Addedutils-deep-get@1.0.0(transitive)
+ Addedutils-deep-set@1.0.1(transitive)
+ Addedutils-indexof@1.0.0(transitive)
+ Addedutils-regex-from-string@1.0.0(transitive)
+ Addedvalidate.io-array@1.0.6(transitive)
+ Addedvalidate.io-array-like@1.0.2(transitive)
+ Addedvalidate.io-boolean-primitive@1.0.0(transitive)
+ Addedvalidate.io-buffer@1.0.2(transitive)
+ Addedvalidate.io-contains@1.0.0(transitive)
+ Addedvalidate.io-function@1.0.2(transitive)
+ Addedvalidate.io-integer@1.0.5(transitive)
+ Addedvalidate.io-integer-primitive@1.0.0(transitive)
+ Addedvalidate.io-matrix-like@1.0.2(transitive)
+ Addedvalidate.io-nan@1.0.3(transitive)
+ Addedvalidate.io-nan-primitive@1.0.0(transitive)
+ Addedvalidate.io-nonnegative-integer@1.0.0(transitive)
+ Addedvalidate.io-nonnegative-integer-array@1.0.1(transitive)
+ Addedvalidate.io-number@1.0.3(transitive)
+ Addedvalidate.io-number-primitive@1.0.0(transitive)
+ Addedvalidate.io-number-primitive-array@1.0.0(transitive)
+ Addedvalidate.io-object@1.0.4(transitive)
+ Addedvalidate.io-string-primitive@1.0.1(transitive)
+ Addedvalidate.io-typed-array-like@1.0.1(transitive)
- Removedml-array-normed@^1.3.2
- Removedobject-hash@^2.0.3
- Removedis-any-array@2.0.1(transitive)
- Removedml-array-max@1.2.4(transitive)
- Removedml-array-normed@1.3.7(transitive)
- Removedml-array-sum@1.1.6(transitive)
- Removedml-peak-shape-generator@0.10.2(transitive)
- Removedobject-hash@2.2.0(transitive)