Skip to content

Commit c0fa0c0

Browse files
committed
GSD: Memory leak for a bad conditioned loop
Solved a memory leak, and improved the code speed 100X!!!!!
1 parent 759ad4b commit c0fa0c0

File tree

4 files changed

+89
-39
lines changed

4 files changed

+89
-39
lines changed

src/gsd.js

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,10 @@ function gsd(x, y, options){
7878
}
7979
}
8080
//console.log(maxY+"x"+maxDy+"x"+maxDdy);
81+
8182
var minddY = [];
82-
var intervals = [];
83+
var intervalL = [];
84+
var intervalR = [];
8385
var lastMax = null;
8486
var lastMin = null;
8587
var broadMask = new Array();
@@ -92,7 +94,9 @@ function gsd(x, y, options){
9294
lastMin = X[i];
9395
//console.log("min "+lastMin);
9496
if(dx>0&&lastMax!=null){
95-
intervals.push( [lastMax , lastMin] );
97+
intervalL.push(lastMax);
98+
intervalR.push(lastMin);
99+
96100
}
97101
}
98102

@@ -101,11 +105,12 @@ function gsd(x, y, options){
101105
lastMax = X[i];
102106
//console.log("max "+lastMax);
103107
if(dx<0&&lastMin!=null){
104-
intervals.push( [lastMax , lastMin] );
108+
intervalL.push(lastMax);
109+
intervalR.push(lastMin);
105110
}
106111
}
107112
if ((ddY[i] < ddY[i-1]) && (ddY[i] < ddY[i+1])) {
108-
minddY.push( [X[i], Y[i], i] ); // TODO should we change this to have 3 arrays ? Huge overhead creating arrays
113+
minddY.push(i);//( [X[i], Y[i], i] ); // TODO should we change this to have 3 arrays ? Huge overhead creating arrays
109114
if(Math.abs(ddY[i])>options.broadRatio*maxDdy){ // TODO should this be a parameter =
110115
broadMask.push(false);
111116
}
@@ -118,55 +123,58 @@ function gsd(x, y, options){
118123
realTopDetection(minddY,X,Y);
119124
}
120125
//
121-
//console.log(intervals);
126+
//console.log(intervalL.length+" "+minddY.length+" "+broadMask.length);
122127
var signals = [];
123-
128+
var lastK = 0,possible, k, f,frequency, distanceJ, minDistance, gettingCloser;
124129
for (var j = 0; j < minddY.length; j++){
125-
var f = minddY[j];
126-
var frequency = f[0];
127-
var possible = [];
128-
for (var k=0; k<intervals.length; k++){
129-
var i = intervals[k];
130-
if(Math.abs(frequency-(i[0]+i[1])/2)<Math.abs(i[0]-i[1])/2)
131-
possible.push(i);
132-
}
133-
//console.log("possible "+possible.length);
134-
if (possible.length > 0)
135-
if (possible.length == 1)
136-
{
137-
var inter = possible[0];
138-
var linewidth = Math.abs(inter[1] - inter[0]);
139-
var height = f[1];
140-
//console.log(height);
141-
if (Math.abs(height) > options.minMaxRatio*maxY) {
142-
signals.push({
143-
x: frequency,
144-
y: (height-yCorrection.b)/yCorrection.m,
145-
width: linewidth,//*widthCorrection
146-
soft:broadMask[j]
147-
})
148-
}
130+
frequency = X[minddY[j]];//minddY[j][0];
131+
possible = -1;
132+
k=lastK+1;
133+
minDistance = Number.MAX_VALUE;
134+
distanceJ = 0;
135+
gettingCloser=true;
136+
while(possible==-1&&k<intervalL.length&&gettingCloser){
137+
distanceJ = Math.abs(frequency-(intervalL[k]+intervalR[k])/2);
138+
//Still getting closer?
139+
if(distanceJ<minDistance){
140+
minDistance = distanceJ;
141+
}
142+
else{
143+
gettingCloser = false;
144+
}
145+
if( distanceJ <Math.abs(intervalL[k]-intervalR[k])/2){
146+
possible=k;
147+
lastK = k;
149148
}
150-
else
151-
{
152-
//TODO: nested peaks
153-
// console.log("Nested "+possible);
149+
k++;
150+
}
151+
//console.log(lastK+" "+intervalL.length+" possible "+k);
152+
if (possible!=-1){
153+
//console.log(height);
154+
if (Math.abs(Y[minddY[j]]) > options.minMaxRatio*maxY) {
155+
signals.push({
156+
x: frequency,
157+
y: (Y[minddY[j]]-yCorrection.b)/yCorrection.m,
158+
width:Math.abs(intervalR[possible] - intervalL[possible]),//widthCorrection
159+
soft:broadMask[j]
160+
})
154161
}
162+
}
155163
}
156164

157165
signals.sort(function (a, b) {
158166
return a.x - b.x;
159167
});
160168

161-
162169
return signals;
170+
163171
}
164172

165173
function realTopDetection(peakList, x, y){
166174
var listP = [];
167175
var alpha, beta, gamma, p,currentPoint;
168176
for(var j=0;j<peakList.length;j++){
169-
currentPoint = peakList[j][2];
177+
currentPoint = peakList[j];//peakList[j][2];
170178
//The detected peak could be moved 1 or 2 unit to left or right.
171179
if(y[currentPoint-1]>=y[currentPoint-2]
172180
&&y[currentPoint-1]>=y[currentPoint]) {
@@ -198,8 +206,8 @@ function realTopDetection(peakList, x, y){
198206
gamma = 20 * Math.log10(y[currentPoint + 1]);
199207
p = 0.5 * (alpha - gamma) / (alpha - 2 * beta + gamma);
200208

201-
peakList[j][0] = x[currentPoint] + (x[currentPoint]-x[currentPoint-1])*p;
202-
peakList[j][1] = y[currentPoint] - 0.25 * (y[currentPoint - 1]
209+
x[peakList[j]] = x[currentPoint] + (x[currentPoint]-x[currentPoint-1])*p;
210+
y[peakList[j]] = y[currentPoint] - 0.25 * (y[currentPoint - 1]
203211
- [currentPoint + 1]) * p;//signal.peaks[j].intensity);
204212
}
205213
}

test/bigLowS2NSpectrum.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Created by acastillo on 2/2/16.
3+
*/
4+
'use strict';
5+
6+
var fs = require('fs');
7+
var peakPicking = require("../src/index");
8+
9+
describe('Global spectra deconvolution NMR spectra', function () {
10+
11+
// Test case obtained from Pag 443, Chap 8.
12+
it('Should give 1 broad peak and around 14 other peaks', function () {
13+
var spectrum=JSON.parse(fs.readFileSync('./test/bigLowS2NSpectrum.json', 'utf-8'));
14+
15+
16+
var pp = peakPicking.gsd(spectrum[0],spectrum[1],
17+
{noiseLevel: 57000.21889405926,//1049200.537996172/2,
18+
minMaxRatio:0.01,broadRatio:0.0025,
19+
sgOptions:{windowSize: 13,polynomial: 3}
20+
}
21+
);
22+
23+
pp.length.should.approximately(186,1);
24+
peakPicking.post.joinBroadPeaks(pp,{width:0.25});
25+
pp.length.should.approximately(150,1);
26+
27+
/*var result = peakPicking.gsd(spectrum[0],spectrum[1], {noiseLevel: 57000.21889405926*0.8,
28+
minMaxRatio:0.005,
29+
broadRatio:0.0025,
30+
sgOptions:{windowSize: 9,
31+
polynomial: 3}
32+
}
33+
);
34+
console.log(result.length);
35+
var last = peakPicking.post.joinBroadPeaks(result,{width:0.25});
36+
console.log(result.length);
37+
*/
38+
39+
40+
});
41+
});

test/bigLowS2Nspectrum.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

test/massPeakPicking.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('Check the peak picking of a simulated mass spectrum', function () {
2525

2626
it('Check result', function () {
2727
var result=peakPicking.gsd(x, y, {noiseLevel: noiseLevel, minMaxRatio:0, broadRatio:0,smoothY:false,realTopDetection:true});
28-
result = peakPicking.optimize(result,x,y,1,"gaussian");
28+
result = peakPicking.post.optimizePeaks(result,x,y,1,"gaussian");
2929

3030
result[0].x.should.approximately(69.938,0.02);
3131
result[0].y.should.approximately(max,0.01);

0 commit comments

Comments
 (0)