11var Opt = require ( "ml-optimize-lorentzian" ) ;
22var stats = require ( "ml-stat" ) ;
3+ var extend = require ( 'extend' ) ;
4+ var SG = require ( 'ml-savitzky-golay-generalized' ) ;
5+
6+ var sgDefOptions = {
7+ windowSize : 5 ,
8+ polynomial : 3 ,
9+ } ;
10+
11+
312function gsd ( x , y , options ) {
13+ //options = extend({}, defaultOptions, options);
414 var options = Object . create ( options || { } ) ;
515 if ( options . minMaxRatio === undefined ) options . minMaxRatio = 0.00025 ;
616 if ( options . broadRatio === undefined ) options . broadRatio = 0.00 ;
@@ -9,6 +19,7 @@ function gsd(x, y, options){
919 if ( options . smoothY === undefined ) options . smoothY = true ;
1020 if ( options . realTopDetection === undefined ) options . realTopDetection = false ;
1121
22+ var sgOptions = extend ( { } , sgDefOptions , options . sgOptions ) ;
1223
1324 //Transform y to use the standard algorithm.
1425 var yCorrection = { m :1 , b :0 } ;
@@ -29,28 +40,32 @@ function gsd(x, y, options){
2940 }
3041 }
3142 }
32- // fill convolution frequency axis
33- var X = [ ] ; //x[2:(x.length-2)];
3443
35- // fill Savitzky-Golay polynomes
36- var size = x . length - 4 ;
37- var Y = new Array ( size ) ;
38- var dY = new Array ( size ) ;
39- var ddY = new Array ( size ) ;
40- //var dX = new Array(size);
41- var dx = x [ 1 ] - x [ 0 ] ;
42-
43- for ( var j = 2 ; j < size + 2 ; j ++ ) {
44- dx = x [ j ] - x [ j - 1 ] ;
45- if ( options . smoothY )
46- Y [ j - 2 ] = ( 1 / 35.0 ) * ( - 3 * y [ j - 2 ] + 12 * y [ j - 1 ] + 17 * y [ j ] + 12 * y [ j + 1 ] - 3 * y [ j + 2 ] ) ;
47- else
48- Y [ j - 2 ] = y [ j ] ;
49- X [ j - 2 ] = x [ j ] ;
50- dY [ j - 2 ] = ( 1 / ( 12 * dx ) ) * ( y [ j - 2 ] - 8 * y [ j - 1 ] + 8 * y [ j + 1 ] - y [ j + 2 ] ) ;
51- ddY [ j - 2 ] = ( 1 / ( 7 * dx * dx ) ) * ( 2 * y [ j - 2 ] - y [ j - 1 ] - 2 * y [ j ] - y [ j + 1 ] + 2 * y [ j + 2 ] ) ;
44+ //We have to know if x is equally spaced
45+ var maxDx = 0 , minDx = Number . MAX_VALUE , tmp ;
46+ for ( var i = 0 ; i < x . length - 1 ; i ++ ) {
47+ var tmp = Math . abs ( x [ i + 1 ] - x [ i ] ) ;
48+ if ( tmp < minDx ) {
49+ minDx = tmp ;
50+ }
51+ if ( tmp > maxDx ) {
52+ maxDx = tmp ;
53+ }
5254 }
53-
55+ //If the max difference between delta x is less than 5%, then, we can assume it to be equally spaced variable
56+ if ( ( maxDx - minDx ) / maxDx < 0.05 ) {
57+ var Y = SG ( y , x [ 1 ] - x [ 0 ] , { windowSize :sgOptions . windowSize , polynomial :sgOptions . polynomial , derivative :0 } ) ;
58+ var dY = SG ( y , x [ 1 ] - x [ 0 ] , { windowSize :sgOptions . windowSize , polynomial :sgOptions . polynomial , derivative :1 } ) ;
59+ var ddY = SG ( y , x [ 1 ] - x [ 0 ] , { windowSize :sgOptions . windowSize , polynomial :sgOptions . polynomial , derivative :2 } ) ;
60+ }
61+ else {
62+ var Y = SG ( y , x , { windowSize :sgOptions . windowSize , polynomial :sgOptions . polynomial , derivative :0 } ) ;
63+ var dY = SG ( y , x , { windowSize :sgOptions . windowSize , polynomial :sgOptions . polynomial , derivative :1 } ) ;
64+ var ddY = SG ( y , x , { windowSize :sgOptions . windowSize , polynomial :sgOptions . polynomial , derivative :2 } ) ;
65+ }
66+
67+ var X = x ;
68+ var dx = x [ 1 ] - x [ 0 ] ;
5469 var maxDdy = 0 ;
5570 var maxY = 0 ;
5671 //console.log(Y.length);
@@ -138,53 +153,6 @@ function gsd(x, y, options){
138153 // console.log("Nested "+possible);
139154 }
140155 }
141- /*if(options.broadRatio>0){
142- var broadLines=[[Number.MAX_VALUE,0,0]];
143- //Optimize the possible broad lines
144- var max=0, maxI=0,count=0;
145- var candidates = [],broadLinesS=[];
146- var isPartOf = false;
147-
148- for(var i=broadLines.length-1;i>0;i--){
149- //console.log(broadLines[i][0]+" "+rangeX+" "+Math.abs(broadLines[i-1][0]-broadLines[i][0]));
150- if(Math.abs(broadLines[i-1][0]-broadLines[i][0])<rangeX){
151-
152- candidates.push(broadLines[i]);
153- if(broadLines[i][1]>max){
154- max = broadLines[i][1];
155- maxI = i;
156- }
157- count++;
158- }
159- else{
160- isPartOf = true;
161- if(count>30){ // TODO, an options ?
162- isPartOf = false;
163- //for(var j=0;j<signals.length;j++){
164- // if(Math.abs(broadLines[maxI][0]-signals[j][0])<rangeX)
165- // isPartOf = true;
166- // }
167- //console.log("Was part of "+isPartOf);
168- }
169- if(isPartOf){
170- for(var j=0;j<candidates.length;j++){
171- signals.push([candidates[j][0], candidates[j][1], dx]);
172- }
173- }
174- else{
175- var fitted = Opt.optimizeSingleLorentzian(candidates,{x:candidates[maxI][0],
176- width:Math.abs(candidates[0][0]-candidates[candidates.length-1][0])},
177- []);
178- //console.log(fitted);
179- signals.push([fitted[0][0],fitted[0][1],fitted[0][2]]);
180- }
181- candidates = [];
182- max = 0;
183- maxI = 0;
184- count = 0;
185- }
186- }
187- }*/
188156
189157 signals . sort ( function ( a , b ) {
190158 return a . x - b . x ;
0 commit comments