Skip to content

Commit 42a54fb

Browse files
authored
feat!: major refactoring
The commit refactor the project and add many breaking changes. Please check the README.md for more information. `const peakList = gsd({x:[] ,y:[]}, options` now returns an array of `GSDPeak` that have the following properties: - x: position of the peak on the x axis - y: the height of the peak - width: width at the level of the inflection points - index: index in the 'x' and 'y' array of the peak - ddY: second derivative value at the level of the peak. Allows to identify 'large' (soft) peaks - inflectionPoints: an object with the position of the inflection points - from: { x, index } - to: { x, index } `const peaks = optimizePeaks({x:[] ,y:[]}, peakList, options)` return `GSDPeakOptimized` that contains 5 properties - x: number; - y: number; - width: number; - fwhm: number; - shape: Shape1D;
1 parent 9484d8d commit 42a54fb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1230
-55385
lines changed

README.md

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,39 @@
1-
# global-spectral-deconvolution
1+
# global-spectral-deconvolution and peak optimizer
22

33
[![NPM version][npm-image]][npm-url]
44
[![build status][ci-image]][ci-url]
55
[![Test coverage][codecov-image]][codecov-url]
66
[![npm download][download-image]][download-url]
77

8-
Global Spectra Deconvolution + Peak optimizer
8+
## Global Spectra Deconvolution
99

10-
`gsd`is using an algorithm that is searching for inflection points to determine the position of peaks and the width of the peaks are between the 2 inflection points. The result of GSD yield to an array of object containing {x, y fwhm and width}. However this width is based on the inflection point and may be different from the 'fwhm' (Full Width Half Maximum).
10+
`gsd`is using an algorithm that is searching for inflection points to determine the position and width of peaks. The width is defined as the distance between the 2 inflection points. Depending the shape of the peak this width may differ from 'fwhm' (Full Width Half Maximum).
1111

12-
The second algorithm (`optimizePeaks`) will optimize the width and FWHM to match the original peak.
12+
Preprocessing of the data involves the following parameters
1313

14-
## [API documentation](http://mljs.github.io/global-spectral-deconvolution/)
14+
- `maxCriteria`: search either for maxima or minima. We will invert the data and the results if searching for a minima
15+
- `sgOptions`: Savitzky-Golay filter that is used to smooth the data for the calculation of the derivatives
16+
- `smoothY`: If this value is true the SG filter is not only applied during the calculation of the derivatives but also on the original data
17+
18+
### gsd({x:[], y:[]}, options)
19+
20+
The result of GSD is an array of GSDPeak:
21+
22+
- x: position of the peak on the x axis
23+
- y: the height of the peak
24+
- width: width at the level of the inflection points
25+
- index: index in the 'x' and 'y' array of the peak
26+
- ddY: second derivative value at the level of the peak. Allows to identify 'large' peaks
27+
- inflectionPoints: an object with the position of the inflection points
28+
- from: { x, index }
29+
- to: { x, index }
1530

1631
## Parameters
1732

1833
#### minMaxRatio=0.00025 (0-1)
1934

2035
Threshold to determine if a given peak should be considered as a noise, bases on its relative height compared to the highest peak.
2136

22-
#### noiseLevel=0 (-inf, inf)
23-
24-
Noise threshold in spectrum units
25-
2637
#### maxCriteria=true [true||false]
2738

2839
Peaks are local maximum(true) or minimum(false)
@@ -39,53 +50,66 @@ Use a quadratic optimizations with the peak and its 3 closest neighbors to deter
3950

4051
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.
4152

42-
#### heightFactor=0
43-
44-
Factor to multiply the calculated height (usually 2).
45-
46-
#### derivativeThreshold=0
47-
48-
Filters based on the amplitude of the first derivative
49-
5053
## Post methods
5154

5255
### GSD.broadenPeaks(peakList, {factor=2, overlap=false})
5356

5457
We enlarge the peaks and add the properties from and to.
5558
By default we enlarge of a factor 2 and we don't allow overlap.
5659

57-
### GSD.joinBroadPeaks
58-
59-
#### broadRatio=0.00 (0-1)
60-
61-
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.
60+
### GSD.optimizePeaks(data, peakList, options)
6261

63-
### GSD.optimizePeaks
62+
Optimize the position (x), max intensity (y), full width at half maximum (fwhm) and the ratio of gaussian contribution (mu) if it's required. It currently supports three kind of shapes: gaussian, lorentzian and pseudovoigt
6463

6564
## Example
6665

6766
```js
6867
import { IsotopicDistribution } from 'mf-global';
69-
import { gsd, optimizePeaks } from '../src';
68+
import { gsd, optimizePeaks } from 'ml-gad';
7069

7170
// generate a sample spectrum of the form {x:[], y:[]}
7271
const data = new IsotopicDistribution('C').getGaussian();
7372

7473
let peaks = gsd(data, {
75-
noiseLevel: 0,
7674
minMaxRatio: 0.00025, // Threshold to determine if a given peak should be considered as a noise
77-
realTopDetection: true,
78-
maxCriteria: true, // inverted:false
79-
smoothY: false,
80-
sgOptions: { windowSize: 7, polynomial: 3 },
75+
realTopDetection: true, // Correction of the x and y coordinates using a quadratic optimizations
76+
maxCriteria: true, // Are we looking for maxima or minima
77+
smoothY: false, // should we smooth the spectra and return smoothed peaks ? Default false.
78+
sgOptions: { windowSize: 7, polynomial: 3 }, // Savitzky-Golay smoothing parameters for first and second derivative calculation
8179
});
82-
console.log(peaks); // array of peaks {x, y, width, fwhw}, width = distance between inflection points
83-
// GSD
80+
console.log(peaks);
81+
/*
82+
array of peaks containing {x, y, width, ddY, inflectionPoints}
83+
- width = distance between inflection points
84+
- ddY = second derivative on the top of the peak
85+
*/
8486

8587
let optimized = optimizePeaks(data, peaks);
86-
console.log(optimized); // array of peaks {x, y, width, fwhm}.
88+
console.log(optimized);
89+
/*
90+
[
91+
{
92+
x: 11.99999999960885,
93+
y: 0.9892695646808637,
94+
shape: { kind: 'gaussian' },
95+
fwhm: 0.010000209455943584,
96+
width: 0.008493395898379276
97+
},
98+
{
99+
x: 13.003354834590702,
100+
y: 0.010699637653261198,
101+
shape: { kind: 'gaussian' },
102+
fwhm: 0.010000226962299321,
103+
width: 0.008493410766908847
104+
}
105+
]
106+
*/
87107
```
88108

109+
i
110+
111+
## [API documentation](http://mljs.github.io/global-spectral-deconvolution/)
112+
89113
## License
90114

91115
[MIT](./LICENSE)

examples/mf.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { gsd, optimizePeaks } from '../src';
88
const data = new IsotopicDistribution('C').getGaussian();
99

1010
let peaks = gsd(data, {
11-
noiseLevel: 0,
1211
minMaxRatio: 0.00025, // Threshold to determine if a given peak should be considered as a noise
1312
realTopDetection: true,
1413
maxCriteria: true, // inverted:false

package.json

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"prepack": "npm run tsc",
2424
"prettier": "prettier --check src",
2525
"prettier-write": "prettier --write src",
26-
"test": "npm run test-only && npm run eslint && npm run check-types",
26+
"test": "npm run test-only && npm run eslint && npm run prettier && npm run check-types",
2727
"test-only": "jest --coverage",
2828
"tsc": "npm run clean && npm run tsc-cjs && npm run tsc-esm",
2929
"tsc-cjs": "tsc --project tsconfig.cjs.json",
@@ -58,30 +58,30 @@
5858
"trailingComma": "all"
5959
},
6060
"devDependencies": {
61-
"@types/jest": "^27.0.3",
61+
"@types/jest": "^27.4.0",
6262
"chemcalc": "^3.4.1",
6363
"cheminfo-build": "^1.1.11",
64-
"eslint": "^8.4.1",
65-
"eslint-config-cheminfo-typescript": "^10.2.4",
66-
"eslint-plugin-jest": "^25.3.0",
64+
"eslint": "^8.9.0",
65+
"eslint-config-cheminfo-typescript": "^10.3.0",
66+
"eslint-plugin-jest": "^26.1.0",
6767
"esm": "^3.2.25",
68-
"jest": "^27.4.5",
68+
"jest": "^27.5.1",
6969
"jest-matcher-deep-close-to": "^3.0.2",
70-
"mf-global": "^1.4.7",
70+
"mf-global": "^1.4.20",
7171
"ml-stat": "^1.3.3",
7272
"nodemon": "^2.0.15",
7373
"prettier": "^2.5.1",
7474
"rimraf": "^3.0.2",
75-
"spectrum-generator": "^6.0.2",
76-
"ts-jest": "^27.1.1",
77-
"typescript": "^4.5.4",
78-
"xy-parser": "^4.0.0"
75+
"spectrum-generator": "^6.0.4",
76+
"ts-jest": "^27.1.3",
77+
"typescript": "^4.5.5",
78+
"xy-parser": "^4.0.1"
7979
},
8080
"dependencies": {
81-
"cheminfo-types": "^0.9.1",
82-
"ml-peak-shape-generator": "^4.0.1",
83-
"ml-savitzky-golay-generalized": "2.0.3",
84-
"ml-spectra-fitting": "^3.0.3",
85-
"ml-spectra-processing": "^8.0.3"
81+
"cheminfo-types": "^0.10.1",
82+
"ml-peak-shape-generator": "^4.0.3",
83+
"ml-savitzky-golay-generalized": "4.0.0",
84+
"ml-spectra-fitting": "^3.0.4",
85+
"ml-spectra-processing": "^10.0.0"
8686
}
8787
}

src/GSDBroadenPeak.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export interface GSDBroadenPeak {
2+
x: number;
3+
y: number;
4+
width: number;
5+
index: number;
6+
from: { x: number };
7+
to: { x: number };
8+
}

src/GSDPeak.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
export interface GSDPeak {
2+
x: number;
3+
y: number;
4+
/**
5+
* Width at the level of the inflection points
6+
*/
7+
width: number;
8+
/**
9+
* index in the 'x' and 'y' array of the peak
10+
*/
11+
index: number;
12+
/**
13+
* second derivative at the level of the peak
14+
* This allows to determine if a peak is soft or not
15+
*/
16+
ddY: number;
17+
inflectionPoints: {
18+
from: { x: number; index: number };
19+
to: { x: number; index: number };
20+
};
21+
}

src/GSDPeakOptimized.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Shape1D } from 'ml-peak-shape-generator';
2+
3+
export interface GSDPeakOptimized {
4+
x: number;
5+
y: number;
6+
width: number;
7+
fwhm: number;
8+
shape: Shape1D;
9+
}

src/__tests__/bigLowS2NSpectrum.test.ts

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/__tests__/broadNMR.test.ts

Lines changed: 0 additions & 44 deletions
This file was deleted.

0 commit comments

Comments
 (0)