Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ml-gsd

Package Overview
Dependencies
Maintainers
5
Versions
77
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ml-gsd - npm Package Compare versions

Comparing version 1.1.5 to 2.0.0

.eslintrc.yml

2

bower.json
{
"name": "ml-gsd",
"version": "1.1.5",
"version": "1.1.6",
"description": "Global Spectra Deconvolution",

@@ -5,0 +5,0 @@ "keywords": [

{
"name": "ml-gsd",
"version": "1.1.5",
"version": "2.0.0",
"description": "Global Spectra Deconvolution",

@@ -11,2 +11,4 @@ "main": "src/index.js",

"scripts": {
"eslint": "eslint src test",
"eslint-fix": "npm run eslint -- --fix",
"test": "mocha --require should --reporter mocha-better-spec-reporter --recursive",

@@ -27,2 +29,5 @@ "build": "cheminfo build --root GSD"

"author": "Andres Castillo",
"contributors": [
"Miguel Asencio <maasencioh@gmail.com> (https://github.com/maasencioh)"
],
"license": "MIT",

@@ -34,6 +39,10 @@ "bugs": {

"devDependencies": {
"cheminfo-tools": "^1.0.2",
"cheminfo-tools": "^1.3.1",
"eslint": "^3.4.0",
"eslint-config-cheminfo": "^1.1.2",
"eslint-plugin-no-only-tests": "^1.1.0",
"mocha": "^2.2.5",
"mocha-better-spec-reporter": "^2.1.1",
"should": "^7.0.2",
"ml-stat": "^1.1.0",
"chemcalc": "^3.0.6"

@@ -43,3 +52,2 @@ },

"ml-optimize-lorentzian": "0.1.1",
"ml-stat": "^1.1.0",
"xy-parser": "^1.2.0",

@@ -46,0 +54,0 @@ "ml-savitzky-golay-generalized": "1.1.0",

# global-spectral-deconvolution
[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[![David deps][david-image]][david-url]
[![npm download][download-image]][download-url]
Global Spectra Deconvolution + Peak optimizer

@@ -8,6 +13,6 @@

#### minMaxRatio=0.00025 (0-1)
Threshold to determine if a given peak should be considered as a noise, bases on its relative height compared to the higest peak.
Threshold to determine if a given peak should be considered as a noise, bases on its relative height compared to the highest peak.
#### broadRatio=0.00 (0-1)
If broadRatio is higher than 0, then all the peaks which second derivative smaller than broadRatio*maxAbsSecondDerivative will be marked with the soft mask equal to true.
If `broadRatio` is higher than 0, then all the peaks which second derivative smaller than `broadRatio * maxAbsSecondDerivative` will be marked with the soft mask equal to true.

@@ -24,23 +29,52 @@ #### noiseLevel=0 (-inf, inf)

#### realTopDetection=false [true||false]
Use a cuadratic optmizations with the peak and its 3 closest neighbors to determine the true x,y values of the peak?
Use a quadratic optimizations with the peak and its 3 closest neighbors to determine the true x,y values of the peak?
#### sgOptions={windowSize: 5, polynomial: 3}
Savitzky-Golay paramters. windowSize should be odd; polynomial is the degree of the polinomial to use in the approximations. > 2
Savitzky-Golay parameters. windowSize should be odd; polynomial is the degree of the polynomial to use in the approximations. It should be bigger than 2.
#### heightFactor=0
Factor to multiply the calculated height (usually 2).
#### boundaries=false
Return also the inflection points of the peaks
#### derivativeThreshold=0
Filters based on the amplitude of the first derivative
## Example
```
```js
var CC = require('chemcalc');
var Stat = require('ml-stat');
var peakPicking = require("../src/index");
var peakPicking = require('ml-gsd');
var spectrum=CC.analyseMF("Cl2.Br2", {isotopomers:'arrayXXYY', fwhm:0.01, gaussianWidth: 11});
var xy=spectrum.arrayXXYY;
var x=xy[0];
var y=xy[1];
var spectrum = CC.analyseMF("Cl2.Br2", {isotopomers:'arrayXXYY', fwhm:0.01, gaussianWidth: 11});
var xy = spectrum.arrayXXYY;
var x = xy[0];
var y = xy[1];
//Just a fake noiseLevel
var noiseLevel=Stat.array.median(y.filter(function(a) {return (a>0)}))*3;
var noiseLevel = Stat.array.median(y.filter(function(a) {return (a > 0)})) * 3;
var result=peakPicking.gsd(x, y, {noiseLevel: noiseLevel, minMaxRatio:0, broadRatio:0,smoothY:false,realTopDetection:true});
result = peakPicking.post.optimizePeaks(result,x,y,1,"gaussian");
var options = {
noiseLevel: noiseLevel,
minMaxRatio:0,
broadRatio:0,
smoothY:false,
realTopDetection:true
};
var result = peakPicking.gsd(x, y, options);
result = peakPicking.post.optimizePeaks(result, x, y, 1, "gaussian");
```
## License
[MIT](./LICENSE)
[npm-image]: https://img.shields.io/npm/v/ml-gsd.svg?style=flat-square
[npm-url]: https://npmjs.org/package/ml-gsd
[travis-image]: https://img.shields.io/travis/mljs/global-spectral-deconvolution/master.svg?style=flat-square
[travis-url]: https://travis-ci.org/mljs/global-spectral-deconvolution
[david-image]: https://img.shields.io/david/mljs/global-spectral-deconvolution.svg?style=flat-square
[david-url]: https://david-dm.org/mljs/global-spectral-deconvolution
[download-image]: https://img.shields.io/npm/dm/ml-gsd.svg?style=flat-square
[download-url]: https://npmjs.org/package/ml-gsd

@@ -1,35 +0,58 @@

var Opt = require("ml-optimize-lorentzian");
var stats = require("ml-stat");
var extend = require('extend');
var SG = require('ml-savitzky-golay-generalized');
'use strict';
var sgDefOptions = {
windowSize: 9,
polynomial: 3
const extend = require('extend');
const SG = require('ml-savitzky-golay-generalized');
const defaultOptions = {
sgOptions: {
windowSize: 9,
polynomial: 3
},
minMaxRatio: 0.00025,
broadRatio: 0.00,
maxCriteria: true,
smoothY: true,
realTopDetection: false,
heightFactor: 0,
boundaries: false,
derivativeThreshold: -1
};
/**
* Global spectra deconvolution
* @param {Array<Number>} x - Independent variable
* @param {Array<Number>} yIn - Dependent variable
* @param {Object} [options] - Options object
* @param {Object} [options.sgOptions] - Options object for Savitzky-Golay filter. See https://github.com/mljs/savitzky-golay-generalized#options
* @param {Number} [options.sgOptions.windowSize = 9] - points to use in the approximations
* @param {Number} [options.sgOptions.polynomial = 3] - degree of the polynomial to use in the approximations
* @param {Number} [options.minMaxRatio = 0.00025] - Threshold to determine if a given peak should be considered as a noise
* @param {Number} [options.broadRatio = 0.00] - If `broadRatio` is higher than 0, then all the peaks which second derivative
* smaller than `broadRatio * maxAbsSecondDerivative` will be marked with the soft mask equal to true.
* @param {Number} [options.noiseLevel = 0] - Noise threshold in spectrum units
* @param {Boolean} [options.maxCriteria = true] - Peaks are local maximum(true) or minimum(false)
* @param {Boolean} [options.smoothY = true] - Select the peak intensities from a smoothed version of the independent variables
* @param {Boolean} [options.realTopDetection = false] - Use a quadratic optimizations with the peak and its 3 closest neighbors
* to determine the true x,y values of the peak?
* @param {Number} [options.heightFactor = 0] - Factor to multiply the calculated height (usually 2)
* @param {Boolean} [options.boundaries = false] - Return also the inflection points of the peaks
* @param {Number} [options.derivativeThreshold = -1] - Filters based on the amplitude of the first derivative
* @return {Array<Object>}
*/
function gsd(x, yIn, options) {
options = extend({}, defaultOptions, options);
let sgOptions = options.sgOptions;
const y = [].concat(yIn);
function gsd(x, y, options){
//options = extend({}, defaultOptions, options);
var options=Object.create(options || {});
if (options.minMaxRatio===undefined) options.minMaxRatio=0.00025;
if (options.broadRatio===undefined) options.broadRatio=0.00;
if (options.noiseLevel===undefined) options.noiseLevel=undefined;
if (options.noiseFactor===undefined) options.noiseFactor=3;
if (options.maxCriteria===undefined) options.maxCriteria=true;
if (options.smoothY===undefined) options.smoothY=true;
if (options.realTopDetection===undefined) options.realTopDetection=false;
var sgOptions = extend({}, sgDefOptions, options.sgOptions);
//console.log(JSON.stringify(stats.array.minMax(y)));
if(options.noiseLevel===undefined){
//We have to know if x is equally spaced
var maxDx=0, minDx=Number.MAX_VALUE,tmp;
for(var i=0;i< x.length-1;i++){
var tmp = Math.abs(x[i+1]-x[i]);
if(tmp<minDx){
if (!('noiseLevel' in options)) {
// We have to know if x is equally spaced
var maxDx = 0,
minDx = Number.MAX_VALUE,
tmp;
for (let i = 0; i < x.length - 1; ++i) {
tmp = Math.abs(x[i + 1] - x[i]);
if (tmp < minDx) {
minDx = tmp;
}
if(tmp>maxDx){
if (tmp > maxDx) {
maxDx = tmp;

@@ -39,24 +62,19 @@ }

if((maxDx-minDx)/maxDx<0.05){
if ((maxDx - minDx) / maxDx < 0.05) {
options.noiseLevel = getNoiseLevel(y);
//console.log(options.noiseLevel+" "+stats.array.median(y));
}
else{
} else {
options.noiseLevel = 0;
}
}
//console.log("options.noiseLevel "+options.noiseLevel);
y=[].concat(y);
var yCorrection = {m:1, b:options.noiseLevel};
if(!options.maxCriteria){
yCorrection.m =-1;
yCorrection.b*=-1;
const yCorrection = {m: 1, b: options.noiseLevel};
if (!options.maxCriteria) {
yCorrection.m = -1;
yCorrection.b *= -1;
}
for (var i=0; i<y.length; i++){
y[i]=yCorrection.m*y[i]-yCorrection.b;
for (let i = 0; i < y.length; i++) {
y[i] = yCorrection.m * y[i] - yCorrection.b;
}
for (var i=0; i<y.length; i++) {
for (let i = 0; i < y.length; i++) {
if (y[i] < 0) {

@@ -66,122 +84,141 @@ y[i] = 0;

}
//If the max difference between delta x is less than 5%, then, we can assume it to be equally spaced variable
var Y = y;
if((maxDx-minDx)/maxDx<0.05){
if(options.smoothY)
Y = SG(y, x[1]-x[0], {windowSize:sgOptions.windowSize, polynomial:sgOptions.polynomial,derivative:0});
var dY = SG(y, x[1]-x[0], {windowSize:sgOptions.windowSize, polynomial:sgOptions.polynomial,derivative:1});
var ddY = SG(y, x[1]-x[0], {windowSize:sgOptions.windowSize, polynomial:sgOptions.polynomial,derivative:2});
// If the max difference between delta x is less than 5%, then, we can assume it to be equally spaced variable
let Y = y;
let dY, ddY;
if ((maxDx - minDx) / maxDx < 0.05) {
if (options.smoothY)
Y = SG(y, x[1] - x[0], {windowSize: sgOptions.windowSize, polynomial: sgOptions.polynomial, derivative: 0});
dY = SG(y, x[1] - x[0], {windowSize: sgOptions.windowSize, polynomial: sgOptions.polynomial, derivative: 1});
ddY = SG(y, x[1] - x[0], {windowSize: sgOptions.windowSize, polynomial: sgOptions.polynomial, derivative: 2});
} else {
if (options.smoothY)
Y = SG(y, x, {windowSize: sgOptions.windowSize, polynomial: sgOptions.polynomial, derivative: 0});
dY = SG(y, x, {windowSize: sgOptions.windowSize, polynomial: sgOptions.polynomial, derivative: 1});
ddY = SG(y, x, {windowSize: sgOptions.windowSize, polynomial: sgOptions.polynomial, derivative: 2});
}
else{
if(options.smoothY)
Y = SG(y, x, {windowSize:sgOptions.windowSize, polynomial:sgOptions.polynomial,derivative:0});
var dY = SG(y, x, {windowSize:sgOptions.windowSize, polynomial:sgOptions.polynomial,derivative:1});
var ddY = SG(y, x, {windowSize:sgOptions.windowSize, polynomial:sgOptions.polynomial,derivative:2});
}
var X = x;
var dx = x[1]-x[0];
var maxDdy=0;
const X = x;
const dx = x[1] - x[0];
var maxDdy = 0;
var maxY = 0;
//console.log(Y.length);
for (var i = 0; i < Y.length ; i++){
if(Math.abs(ddY[i])>maxDdy){
for (let i = 0; i < Y.length; i++) {
if (Math.abs(ddY[i]) > maxDdy) {
maxDdy = Math.abs(ddY[i]);
}
if(Math.abs(Y[i])>maxY){
if (Math.abs(Y[i]) > maxY) {
maxY = Math.abs(Y[i]);
}
}
//console.log(maxY+"x"+maxDy+"x"+maxDdy);
var minddY = [];
var intervalL = [];
var intervalR = [];
var lastMax = null;
var lastMin = null;
var broadMask = new Array();
//console.log(dx);
//By the intermediate value theorem We cannot find 2 consecutive maxima or minima
for (var i = 1; i < Y.length -1 ; i++){
//console.log(dY[i]);
if ((dY[i] < dY[i-1]) && (dY[i] <= dY[i+1])||
(dY[i] <= dY[i-1]) && (dY[i] < dY[i+1])) {
lastMin = X[i];
//console.log("min "+lastMin);
if(dx>0&&lastMax!=null){
intervalL.push(lastMax);
intervalR.push(lastMin);
var minddY = new Array(Y.length - 2);
var intervalL = new Array(Y.length);
var intervalR = new Array(Y.length);
var broadMask = new Array(Y.length - 2);
var minddYLen = 0;
var intervalLLen = 0;
var intervalRLen = 0;
var broadMaskLen = 0;
// By the intermediate value theorem We cannot find 2 consecutive maximum or minimum
for (let i = 1; i < Y.length - 1; ++i) {
// filter based on derivativeThreshold
if (Math.abs(dY[i]) > options.derivativeThreshold) {
// Minimum in first derivative
if ((dY[i] < dY[i - 1]) && (dY[i] <= dY[i + 1]) ||
(dY[i] <= dY[i - 1]) && (dY[i] < dY[i + 1])) {
lastMin = {
x: X[i],
index: i
};
if (dx > 0 && lastMax !== null) {
intervalL[intervalLLen++] = lastMax;
intervalR[intervalRLen++] = lastMin;
}
}
}
if ((dY[i] >= dY[i-1]) && (dY[i] > dY[i+1])||
(dY[i] > dY[i-1]) && (dY[i] >= dY[i+1])) {
lastMax = X[i];
//console.log("max "+lastMax);
if(dx<0&&lastMin!=null){
intervalL.push(lastMax);
intervalR.push(lastMin);
// Maximum in first derivative
if ((dY[i] >= dY[i - 1]) && (dY[i] > dY[i + 1]) ||
(dY[i] > dY[i - 1]) && (dY[i] >= dY[i + 1])) {
lastMax = {
x: X[i],
index: i
};
if (dx < 0 && lastMin !== null) {
intervalL[intervalLLen++] = lastMax;
intervalR[intervalRLen++] = lastMin;
}
}
}
if ((ddY[i] < ddY[i-1]) && (ddY[i] < ddY[i+1])) {
minddY.push(i);//( [X[i], Y[i], i] ); // TODO should we change this to have 3 arrays ? Huge overhead creating arrays
if(Math.abs(ddY[i])>options.broadRatio*maxDdy){ // TODO should this be a parameter =
broadMask.push(false);
}
else{
broadMask.push(true);
}
// Minimum in second derivative
if ((ddY[i] < ddY[i - 1]) && (ddY[i] < ddY[i + 1])) {
// TODO should we change this to have 3 arrays ? Huge overhead creating arrays
minddY[minddYLen++] = i; //( [X[i], Y[i], i] );
broadMask[broadMaskLen++] = Math.abs(ddY[i]) <= options.broadRatio * maxDdy;
}
}
//
//console.log(intervalL.length+" "+minddY.length+" "+broadMask.length);
var signals = [];
var lastK = 0,possible, k, f,frequency, distanceJ, minDistance, gettingCloser;
for (var j = 0; j < minddY.length; j++){
frequency = X[minddY[j]];//minddY[j][0];
minddY.length = minddYLen;
intervalL.length = intervalLLen;
intervalR.length = intervalRLen;
broadMask.length = broadMaskLen;
let signals = new Array(minddY.length);
let signalsLen = 0;
let lastK = 0;
let possible, frequency, distanceJ, minDistance, gettingCloser;
for (let j = 0; j < minddY.length; ++j) {
frequency = X[minddY[j]];
possible = -1;
k=lastK+1;
let k = lastK + 1;
minDistance = Number.MAX_VALUE;
distanceJ = 0;
gettingCloser=true;
while(possible==-1&&k<intervalL.length&&gettingCloser){
distanceJ = Math.abs(frequency-(intervalL[k]+intervalR[k])/2);
gettingCloser = true;
while (possible === -1 && (k < intervalL.length) && gettingCloser) {
distanceJ = Math.abs(frequency - (intervalL[k].x + intervalR[k].x) / 2);
//Still getting closer?
if(distanceJ<minDistance){
if (distanceJ < minDistance) {
minDistance = distanceJ;
}
else{
} else {
gettingCloser = false;
}
if( distanceJ <Math.abs(intervalL[k]-intervalR[k])/2){
possible=k;
if (distanceJ < Math.abs(intervalL[k].x - intervalR[k].x) / 2) {
possible = k;
lastK = k;
}
k++;
++k;
}
//console.log(lastK+" "+intervalL.length+" possible "+k);
if (possible!=-1){
//console.log(height);
if (Math.abs(Y[minddY[j]]) > options.minMaxRatio*maxY) {
signals.push({
i:minddY[j],
if (possible !== -1) {
if (Math.abs(Y[minddY[j]]) > options.minMaxRatio * maxY) {
signals[signalsLen++] = {
index: minddY[j],
x: frequency,
y: (Y[minddY[j]]-yCorrection.b)/yCorrection.m,
width:Math.abs(intervalR[possible] - intervalL[possible]),//widthCorrection
soft:broadMask[j]
})
y: (Y[minddY[j]] + yCorrection.b) / yCorrection.m,
width: Math.abs(intervalR[possible].x - intervalL[possible].x), //widthCorrection
soft: broadMask[j]
};
if (options.boundaries) {
signals[signalsLen - 1].left = intervalL[possible];
signals[signalsLen - 1].right = intervalR[possible];
}
if (options.heightFactor) {
let yLeft = Y[intervalL[possible].index];
let yRight = Y[intervalR[possible].index];
signals[signalsLen - 1].height = options.heightFactor * (signals[signalsLen - 1].y - ((yLeft + yRight) / 2));
}
}
}
}
signals.length = signalsLen;
if (options.realTopDetection)
realTopDetection(signals, X, Y);
if(options.realTopDetection){
realTopDetection(signals,X,Y);
}
//Correct the values to fit the original spectra data
for(var j=0;j<signals.length;j++){
signals[j].base=options.noiseLevel;
for (let j = 0; j < signals.length; j++) {
signals[j].base = options.noiseLevel;
}

@@ -197,17 +234,17 @@

function getNoiseLevel(y){
var mean = 0,stddev=0;
var length = y.length,i=0;
for(i = 0; i < length; i++){
mean+=y[i];
function getNoiseLevel(y) {
var mean = 0, stddev = 0;
var length = y.length;
for (let i = 0; i < length; ++i) {
mean += y[i];
}
mean/=length;
mean /= length;
var averageDeviations = new Array(length);
for (i = 0; i < length; i++)
for (let i = 0; i < length; ++i)
averageDeviations[i] = Math.abs(y[i] - mean);
averageDeviations.sort();
if (length % 2 == 1) {
stddev = averageDeviations[(length-1)/2] / 0.6745;
if (length % 2 === 1) {
stddev = averageDeviations[(length - 1) / 2] / 0.6745;
} else {
stddev = 0.5*(averageDeviations[length/2]+averageDeviations[length/2-1]) / 0.6745;
stddev = 0.5 * (averageDeviations[length / 2] + averageDeviations[length / 2 - 1]) / 0.6745;
}

@@ -218,30 +255,22 @@

function realTopDetection(peakList, x, y){
//console.log(peakList);
//console.log(x);
//console.log(y);
var listP = [];
var alpha, beta, gamma, p,currentPoint;
for(var j=0;j<peakList.length;j++){
function realTopDetection(peakList, x, y) {
var alpha, beta, gamma, p, currentPoint;
for (var j = 0; j < peakList.length; j++) {
currentPoint = peakList[j].i;//peakList[j][2];
var tmp = currentPoint;
//The detected peak could be moved 1 or 2 unit to left or right.
if(y[currentPoint-1]>=y[currentPoint-2]
&&y[currentPoint-1]>=y[currentPoint]) {
if (y[currentPoint - 1] >= y[currentPoint - 2]
&& y[currentPoint - 1] >= y[currentPoint]) {
currentPoint--;
}
else{
if(y[currentPoint+1]>=y[currentPoint]
&&y[currentPoint+1]>=y[currentPoint+2]) {
} else {
if (y[currentPoint + 1] >= y[currentPoint]
&& y[currentPoint + 1] >= y[currentPoint + 2]) {
currentPoint++;
}
else{
if(y[currentPoint-2]>=y[currentPoint-3]
&&y[currentPoint-2]>=y[currentPoint-1]) {
currentPoint-=2;
}
else{
if(y[currentPoint+2]>=y[currentPoint+1]
&&y[currentPoint+2]>=y[currentPoint+3]) {
currentPoint+=2;
} else {
if (y[currentPoint - 2] >= y[currentPoint - 3]
&& y[currentPoint - 2] >= y[currentPoint - 1]) {
currentPoint -= 2;
} else {
if (y[currentPoint + 2] >= y[currentPoint + 1]
&& y[currentPoint + 2] >= y[currentPoint + 3]) {
currentPoint += 2;
}

@@ -251,5 +280,5 @@ }

}
if(y[currentPoint-1]>0&&y[currentPoint+1]>0
&&y[currentPoint]>=y[currentPoint-1]
&&y[currentPoint]>=y[currentPoint+1]) {
if (y[currentPoint - 1] > 0 && y[currentPoint + 1] > 0
&& y[currentPoint] >= y[currentPoint - 1]
&& y[currentPoint] >= y[currentPoint + 1]) {
alpha = 20 * Math.log10(y[currentPoint - 1]);

@@ -261,6 +290,4 @@ beta = 20 * Math.log10(y[currentPoint]);

//console.log(x[currentPoint]+" "+tmp+" "+currentPoint);
peakList[j].x = x[currentPoint] + (x[currentPoint]-x[currentPoint-1])*p;
peakList[j].y = y[currentPoint] - 0.25 * (y[currentPoint - 1]
- y[currentPoint + 1]) * p;//signal.peaks[j].intensity);
//console.log(y[tmp]+" "+peakList[j].y);
peakList[j].x = x[currentPoint] + (x[currentPoint] - x[currentPoint - 1]) * p;
peakList[j].y = y[currentPoint] - 0.25 * (y[currentPoint - 1] - y[currentPoint + 1]) * p;
}

@@ -270,2 +297,2 @@ }

module.exports=gsd;
module.exports = gsd;

@@ -0,3 +1,4 @@

'use strict';
module.exports.post = require("../src/optimize");
module.exports.gsd = require("../src/gsd");
module.exports.post = require('../src/optimize');
module.exports.gsd = require('../src/gsd');
/**
* Created by acastillo on 9/6/15.
*/
var Opt = require("ml-optimize-lorentzian");
'use strict';
function sampleFunction(from, to, x, y, lastIndex){
var Opt = require('ml-optimize-lorentzian');
function sampleFunction(from, to, x, y, lastIndex) {
var nbPoints = x.length;
var sampleX = [];
var sampleY = [];
var direction = Math.sign(x[1]-x[0]);//Direction of the derivative
if(direction==-1){
lastIndex[0]= x.length-1;
var direction = Math.sign(x[1] - x[0]);//Direction of the derivative
if (direction === -1) {
lastIndex[0] = x.length - 1;
}
var delta = Math.abs(to-from)/2;
var mid = (from+to)/2;
var delta = Math.abs(to - from) / 2;
var mid = (from + to) / 2;
var stop = false;
var index = lastIndex[0];
while(!stop&&index<nbPoints&&index>=0){
if(Math.abs(x[index]-mid)<=delta){
while (!stop && index < nbPoints && index >= 0) {
if (Math.abs(x[index] - mid) <= delta) {
sampleX.push(x[index]);
sampleY.push(y[index]);
index+=direction;
}
//It is outside the range.
else{
if(Math.sign(mid-x[index])==1){
index += direction;
} else {
//It is outside the range.
if (Math.sign(mid - x[index]) === 1) {
//We'll reach the mid going in the current direction
index+=direction;
}
else{
index += direction;
} else {
//There is not more peaks in the current range
stop=true;
stop = true;
}

@@ -39,16 +38,17 @@ }

}
lastIndex[0]=index;
lastIndex[0] = index;
return [sampleX, sampleY];
}
function optimizePeaks(peakList,x,y,n, fnType){
var i, j, lastIndex=[0];
var groups = groupPeaks(peakList,n);
function optimizePeaks(peakList, x, y, n, fnType) {
var i, j, lastIndex = [0];
var groups = groupPeaks(peakList, n);
var result = [];
var factor = 1;
if(fnType=="gaussian")
if (fnType === 'gaussian')
factor = 1.17741;//From https://en.wikipedia.org/wiki/Gaussian_function#Properties
for(i=0;i<groups.length;i++){
var sampling, error, opts;
for (i = 0; i < groups.length; i++) {
var peaks = groups[i].group;
if(peaks.length>1){
if (peaks.length > 1) {
//Multiple peaks

@@ -58,13 +58,13 @@ //console.log("Pending group of overlaped peaks "+peaks.length);

//console.log(groups[i].limits);
var sampling = sampleFunction(groups[i].limits[0]-groups[i].limits[1],groups[i].limits[0]+groups[i].limits[1],x,y,lastIndex);
sampling = sampleFunction(groups[i].limits[0] - groups[i].limits[1], groups[i].limits[0] + groups[i].limits[1], x, y, lastIndex);
//console.log(sampling);
if(sampling[0].length>5){
var error = peaks[0].width/1000;
var opts = [ 3, 100, error, error, error, error*10, error*10, 11, 9, 1 ];
if (sampling[0].length > 5) {
error = peaks[0].width / 1000;
opts = [ 3, 100, error, error, error, error * 10, error * 10, 11, 9, 1 ];
//var gauss = Opt.optimizeSingleGaussian(sampling[0], sampling[1], opts, peaks);
var optPeaks = [];
if(fnType=="gaussian")
if (fnType === 'gaussian')
optPeaks = Opt.optimizeGaussianSum(sampling, peaks, opts);
else{
if(fnType=="lorentzian"){
else {
if (fnType === 'lorentzian') {
optPeaks = Opt.optimizeLorentzianSum(sampling, peaks, opts);

@@ -74,29 +74,28 @@ }

//console.log(optPeak);
for(j=0;j<optPeaks.length;j++){
result.push({x:optPeaks[j][0][0],y:optPeaks[j][1][0],width:optPeaks[j][2][0]*factor});
for (j = 0; j < optPeaks.length; j++) {
result.push({x: optPeaks[j][0][0], y: optPeaks[j][1][0], width: optPeaks[j][2][0] * factor});
}
}
}
else{
} else {
//Single peak
peaks = peaks[0];
var sampling = sampleFunction(peaks.x-n*peaks.width,
peaks.x+n*peaks.width,x,y,lastIndex);
sampling = sampleFunction(peaks.x - n * peaks.width,
peaks.x + n * peaks.width, x, y, lastIndex);
//console.log("here2");
//console.log(groups[i].limits);
if(sampling[0].length>5){
var error = peaks.width/1000;
var opts = [ 3, 100, error, error, error, error*10, error*10, 11, 9, 1 ];
if (sampling[0].length > 5) {
error = peaks.width / 1000;
opts = [3, 100, error, error, error, error * 10, error * 10, 11, 9, 1];
//var gauss = Opt.optimizeSingleGaussian(sampling[0], sampling[1], opts, peaks);
//var gauss = Opt.optimizeSingleGaussian([sampling[0],sampling[1]], peaks, opts);
var optPeak = [];
if(fnType=="gaussian")
var optPeak = Opt.optimizeSingleGaussian([sampling[0],sampling[1]], peaks, opts);
else{
if(fnType=="lorentzian"){
var optPeak = Opt.optimizeSingleLorentzian([sampling[0],sampling[1]], peaks, opts);
if (fnType === 'gaussian')
optPeak = Opt.optimizeSingleGaussian([sampling[0], sampling[1]], peaks, opts);
else {
if (fnType === 'lorentzian') {
optPeak = Opt.optimizeSingleLorentzian([sampling[0], sampling[1]], peaks, opts);
}
}
//console.log(optPeak);
result.push({x:optPeak[0][0],y:optPeak[1][0],width:optPeak[2][0]*factor}); // From https://en.wikipedia.org/wiki/Gaussian_function#Properties}
result.push({x: optPeak[0][0], y: optPeak[1][0], width: optPeak[2][0] * factor}); // From https://en.wikipedia.org/wiki/Gaussian_function#Properties}
}

@@ -109,54 +108,53 @@ }

function groupPeaks(peakList,nL){
function groupPeaks(peakList, nL) {
var group = [];
var groups = [];
var i, j;
var limits = [peakList[0].x,nL*peakList[0].width];
var limits = [peakList[0].x, nL * peakList[0].width];
var upperLimit, lowerLimit;
//Merge forward
for(i=0;i<peakList.length;i++){
for (i = 0; i < peakList.length; i++) {
//If the 2 things overlaps
if(Math.abs(peakList[i].x-limits[0])<(nL*peakList[i].width+limits[1])){
if (Math.abs(peakList[i].x - limits[0]) < (nL * peakList[i].width + limits[1])) {
//Add the peak to the group
group.push(peakList[i]);
//Update the group limits
upperLimit = limits[0]+limits[1];
if(peakList[i].x+nL*peakList[i].width>upperLimit){
upperLimit = peakList[i].x+nL*peakList[i].width;
upperLimit = limits[0] + limits[1];
if (peakList[i].x + nL * peakList[i].width > upperLimit) {
upperLimit = peakList[i].x + nL * peakList[i].width;
}
lowerLimit = limits[0]-limits[1];
if(peakList[i].x-nL*peakList[i].width<lowerLimit){
lowerLimit = peakList[i].x-nL*peakList[i].width;
lowerLimit = limits[0] - limits[1];
if (peakList[i].x - nL * peakList[i].width < lowerLimit) {
lowerLimit = peakList[i].x - nL * peakList[i].width;
}
limits = [(upperLimit+lowerLimit)/2,Math.abs(upperLimit-lowerLimit)/2];
limits = [(upperLimit + lowerLimit) / 2, Math.abs(upperLimit - lowerLimit) / 2];
}
else{
groups.push({limits:limits,group:group});
} else {
groups.push({limits: limits, group: group});
//var optmimalPeak = fitSpectrum(group,limits,spectrum);
group=[peakList[i]];
limits = [peakList[i].x,nL*peakList[i].width];
group = [peakList[i]];
limits = [peakList[i].x, nL * peakList[i].width];
}
}
groups.push({limits:limits,group:group});
groups.push({limits: limits, group: group});
//Merge backward
for(i =groups.length-2;i>=0;i--){
for (i = groups.length - 2; i >= 0; i--) {
//The groups overlaps
if(Math.abs(groups[i].limits[0]-groups[i+1].limits[0])<
(groups[i].limits[1]+groups[i+1].limits[1])/2){
for(j=0;j<groups[i+1].group.length;j++){
groups[i].group.push(groups[i+1].group[j]);
if (Math.abs(groups[i].limits[0] - groups[i + 1].limits[0]) <
(groups[i].limits[1] + groups[i + 1].limits[1]) / 2) {
for (j = 0; j < groups[i + 1].group.length; j++) {
groups[i].group.push(groups[i + 1].group[j]);
}
upperLimit = groups[i].limits[0]+groups[i].limits[1];
if(groups[i+1].limits[0]+groups[i+1].limits[1]>upperLimit){
upperLimit = groups[i+1].limits[0]+groups[i+1].limits[1];
upperLimit = groups[i].limits[0] + groups[i].limits[1];
if (groups[i + 1].limits[0] + groups[i + 1].limits[1] > upperLimit) {
upperLimit = groups[i + 1].limits[0] + groups[i + 1].limits[1];
}
lowerLimit = groups[i].limits[0]-groups[i].limits[1];
if(groups[i+1].limits[0]-groups[i+1].limits[1]<lowerLimit){
lowerLimit = groups[i+1].limits[0]-groups[i+1].limits[1];
lowerLimit = groups[i].limits[0] - groups[i].limits[1];
if (groups[i + 1].limits[0] - groups[i + 1].limits[1] < lowerLimit) {
lowerLimit = groups[i + 1].limits[0] - groups[i + 1].limits[1];
}
//console.log(limits);
groups[i].limits = [(upperLimit+lowerLimit)/2,Math.abs(upperLimit-lowerLimit)/2];
groups[i].limits = [(upperLimit + lowerLimit) / 2, Math.abs(upperLimit - lowerLimit) / 2];
groups.splice(i+1,1);
groups.splice(i + 1, 1);
}

@@ -171,15 +169,14 @@ }

*/
function joinBroadPeaks(peakList, options){
function joinBroadPeaks(peakList, options) {
var width = options.width;
var broadLines=[];
var broadLines = [];
//Optimize the possible broad lines
var max=0, maxI=0,count=1;
var isPartOf = false;
for(var i=peakList.length-1;i>=0;i--){
if(peakList[i].soft){
broadLines.push(peakList.splice(i,1)[0]);
var max = 0, maxI = 0, count = 1;
for (let i = peakList.length - 1; i >= 0; i--) {
if (peakList[i].soft) {
broadLines.push(peakList.splice(i, 1)[0]);
}
}
//Push a feak peak
broadLines.push({x:Number.MAX_VALUE});
broadLines.push({x: Number.MAX_VALUE});

@@ -190,7 +187,7 @@ var candidates = [[broadLines[0].x,

for(var i=1;i<broadLines.length;i++){
for (let i = 1; i < broadLines.length; i++) {
//console.log(broadLines[i-1].x+" "+broadLines[i].x);
if(Math.abs(broadLines[i-1].x-broadLines[i].x)<width){
candidates.push([broadLines[i].x,broadLines[i].y]);
if(broadLines[i].y>max){
if (Math.abs(broadLines[i - 1].x - broadLines[i].x) < width) {
candidates.push([broadLines[i].x, broadLines[i].y]);
if (broadLines[i].y > max) {
max = broadLines[i].y;

@@ -201,15 +198,15 @@ maxI = i;

count++;
}
else{
if(count>2){
var fitted = Opt.optimizeSingleLorentzian(candidates,
{x: broadLines[maxI].x, y:max, width: Math.abs(candidates[0][0]-candidates[candidates.length-1][0])});
peakList.push({x:fitted[0][0],y:fitted[1][0],width:fitted[2][0],soft:false});
} else {
if (count > 2) {
var fitted = Opt.optimizeSingleLorentzian(candidates,
{x: broadLines[maxI].x, y: max, width: Math.abs(candidates[0][0] - candidates[candidates.length - 1][0])});
peakList.push({x: fitted[0][0], y: fitted[1][0], width: fitted[2][0], soft: false});
}
else{
} else {
//Put back the candidates to the signals list
indexes.map(function(index){peakList.push(broadLines[index])});
indexes.map(function (index) {
peakList.push(broadLines[index]);
});
}
candidates = [[broadLines[i].x,broadLines[i].y]];
candidates = [[broadLines[i].x, broadLines[i].y]];
indexes = [i];

@@ -230,3 +227,5 @@ max = broadLines[i].y;

/*if(options.broadRatio>0){
/*
var isPartOf = true
if(options.broadRatio>0){
var broadLines=[[Number.MAX_VALUE,0,0]];

@@ -279,3 +278,3 @@ //Optimize the possible broad lines

module.exports={optimizePeaks:optimizePeaks,joinBroadPeaks:joinBroadPeaks};
module.exports = {optimizePeaks: optimizePeaks, joinBroadPeaks: joinBroadPeaks};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc