Skip to content

Commit 2ef7a6f

Browse files
committed
Detect the broadPeaks
GSD fails to detect very broad peaks. It returns instead, a lot of sharp peaks. The optimisation procedure aims to convert all those sharp little signals in a single broad peak. A test case is included where the broad peak overlaps with some normal peaks.
1 parent 81e67b4 commit 2ef7a6f

File tree

5 files changed

+92
-3
lines changed

5 files changed

+92
-3
lines changed

src/gsd.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ var SG = require('ml-savitzky-golay-generalized');
55

66
var sgDefOptions = {
77
windowSize: 5,
8-
polynomial: 3,
8+
polynomial: 3
99
};
1010

1111

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11

2-
module.exports.optimize = require("../src/optimize");
2+
module.exports.post = require("../src/optimize");
33
module.exports.gsd = require("../src/gsd");

src/optimize.js

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,67 @@ function groupPeaks(peakList,nL){
159159
}
160160
return groups;
161161
}
162+
/**
163+
* This function try to join the peaks that seems to belong to a broad signal in a single broad peak.
164+
* @param peakList
165+
* @param options
166+
*/
167+
function joinBroadPeaks(peakList, options){
168+
var width = options.width;
169+
var broadLines=[];
170+
//Optimize the possible broad lines
171+
var max=0, maxI=0,count=1;
172+
var isPartOf = false;
173+
for(var i=peakList.length-1;i>=0;i--){
174+
if(peakList[i].soft){
175+
broadLines.push(peakList.splice(i,1)[0]);
176+
}
177+
}
178+
//Push a feak peak
179+
broadLines.push({x:Number.MAX_VALUE});
180+
181+
var candidates = [[broadLines[0].x,
182+
broadLines[0].y]];
183+
var indexes = [0];
184+
185+
for(var i=1;i<broadLines.length;i++){
186+
//console.log(broadLines[i-1].x+" "+broadLines[i].x);
187+
if(Math.abs(broadLines[i-1].x-broadLines[i].x)<width){
188+
candidates.push([broadLines[i].x,broadLines[i].y]);
189+
if(broadLines[i].y>max){
190+
max = broadLines[i].y;
191+
maxI = i;
192+
}
193+
indexes.push(i);
194+
count++;
195+
}
196+
else{
197+
if(count>2){
198+
var fitted = Opt.optimizeSingleLorentzian(candidates,
199+
{x: broadLines[maxI].x, y:max, width: Math.abs(candidates[0][0]-candidates[candidates.length-1][0])});
200+
//console.log(fitted)
201+
peakList.push({x:fitted[0][0],y:fitted[1][0],width:fitted[2][0],soft:false});
202+
203+
}
204+
else{
205+
//Put back the candidates to the signals list
206+
indexes.map(function(index){peakList.push(broadLines[index])});
207+
}
208+
candidates = [[broadLines[i].x,broadLines[i].y]];
209+
indexes = [i];
210+
max = broadLines[i].y;
211+
maxI = i;
212+
count = 1;
213+
}
214+
}
215+
216+
peakList.sort(function (a, b) {
217+
return a.x - b.x;
218+
});
219+
220+
return peakList;
221+
222+
}
162223

163224
/*if(options.broadRatio>0){
164225
var broadLines=[[Number.MAX_VALUE,0,0]];
@@ -208,5 +269,5 @@ function groupPeaks(peakList,nL){
208269
}
209270
}*/
210271

211-
module.exports=optimizePeaks;
272+
module.exports={optimizePeaks:optimizePeaks,joinBroadPeaks:joinBroadPeaks};
212273

test/broadNMR.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
3+
var fs = require('fs');
4+
var peakPicking = require("../src/index");
5+
6+
describe('Global spectra deconvolution NMR spectra', function () {
7+
8+
// Test case obtained from Pag 443, Chap 8.
9+
it('Should give 1 broad peak and around 14 other peaks', function () {
10+
var spectrum=JSON.parse(fs.readFileSync('./test/broadNMR.json', 'utf-8'));
11+
var result = peakPicking.gsd(spectrum[0],spectrum[1], {noiseLevel: 1049200.537996172/2,
12+
minMaxRatio:0.01,
13+
broadRatio:0.0025,
14+
sgOptions:{windowSize: 9,
15+
polynomial: 3}
16+
}
17+
);
18+
var last = peakPicking.post.joinBroadPeaks(result,{width:0.25});
19+
20+
result.length.should.approximately(15,1);
21+
result.map(function(peak){
22+
if(Math.abs(peak.x-4.31)<0.01){
23+
peak.width.should.approximately(0.4,0.02);
24+
}
25+
});
26+
});
27+
});

test/broadNMR.json

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

0 commit comments

Comments
 (0)