chromatography
Advanced tools
Comparing version 2.0.6 to 2.1.0
136
lib/index.js
@@ -8,2 +8,3 @@ 'use strict'; | ||
var mlGsd = require('ml-gsd'); | ||
var max = _interopDefault(require('ml-array-max')); | ||
var binarySearch = _interopDefault(require('binary-search')); | ||
@@ -237,2 +238,21 @@ var chemcalc = require('chemcalc'); | ||
/** | ||
* Calculate bpc | ||
* @param {Chromatogram} chrom - GC/MS chromatogram where make the peak picking | ||
* @return {Array} - Calculated bpc | ||
*/ | ||
function calculateBpc(chrom) { | ||
let ms = chrom.getSerie('ms'); | ||
if (!ms) { | ||
throw new Error('The mass serie must be defined'); | ||
} | ||
var massSpectra = ms.data; | ||
var bpc = []; | ||
for (var massSpectrum of massSpectra) { | ||
bpc.push(max(massSpectrum[1])); | ||
} | ||
return bpc; | ||
} | ||
const ascValue = (a, b) => (a - b); | ||
@@ -286,3 +306,29 @@ | ||
function integrate1D(time, serie, from, to, fromIndex, toIndex) { | ||
function baselineCorrection(total, base, kind) { | ||
switch (kind) { | ||
case 'trapezoid': | ||
return { | ||
integral: total - ((base.end.time - base.start.time) * (base.end.height + base.start.height) / 2), | ||
base | ||
}; | ||
case 'min': | ||
if (base.end.height > base.start.height) { | ||
base.end.height = base.start.height; | ||
return { | ||
integral: total - ((base.end.time - base.start.time) * base.start.height), | ||
base | ||
}; | ||
} else { | ||
base.start.height = base.end.height; | ||
return { | ||
integral: total - ((base.end.time - base.start.time) * base.end.height), | ||
base | ||
}; | ||
} | ||
default: | ||
throw new Error(`Unknown baseline method "${kind}"`); | ||
} | ||
} | ||
function integrate1D(time, serie, from, to, fromIndex, toIndex, baseline) { | ||
if (serie.dimension !== 1) throw new Error('The serie name is not of dimension 1'); | ||
@@ -292,2 +338,3 @@ if (!serie.data) return 0; | ||
let total = 0; | ||
let base = {}; | ||
for (let i = fromIndex; i < toIndex; i++) { | ||
@@ -299,2 +346,3 @@ let timeStart = time[i]; | ||
heightStart = serie.data[i] + (serie.data[i + 1] - serie.data[i]) * (from - timeStart) / (timeEnd - timeStart); | ||
base.start = {height: heightStart, time: from}; | ||
timeStart = from; | ||
@@ -305,3 +353,4 @@ } | ||
if (i === toIndex - 1) { | ||
heightEnd = serie.data[i] + (serie.data[i + 1] - serie.data[i]) * (timeEnd - to) / (timeEnd - timeStart); | ||
heightEnd = serie.data[i] + (serie.data[i + 1] - serie.data[i]) * (to - timeStart) / (timeEnd - timeStart); | ||
base.end = {height: heightEnd, time: to}; | ||
timeEnd = to; | ||
@@ -311,3 +360,14 @@ } | ||
} | ||
return total; | ||
if (baseline) { | ||
return baselineCorrection(total, base, baseline); | ||
} else { | ||
return { | ||
integral: total, | ||
base: { | ||
start: {height: 0, time: from}, | ||
end: {height: 0, time: to} | ||
} | ||
}; | ||
} | ||
} | ||
@@ -342,6 +402,2 @@ | ||
const defaultOptions = { | ||
slot: 1 | ||
}; | ||
/** | ||
@@ -358,6 +414,12 @@ * Returns a mass spectrum that is the integration of all the spectra in a specific range of time | ||
* @param {number} [options.slot = 2] - Define when 2 peaks will be combined | ||
* @param {string} [options.name] - Name of the serie to integrate, by default all the series are integrated | ||
* @param {string|boolean} [options.baseline] - Applies baseline correction | ||
* @return {{serieName: []}} | ||
*/ | ||
function integrate(chromatogram, ranges, options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
function integrate(chromatogram, ranges, options = {}) { | ||
const { | ||
slot = 1, | ||
name = false, | ||
baseline = false | ||
} = options; | ||
@@ -370,3 +432,8 @@ if (!Array.isArray(ranges)) throw new Error('fromTo must be an array of type [from,to]'); | ||
// by default we integrate all the series | ||
var serieNames = chromatogram.getSerieNames(); | ||
let serieNames; | ||
if (name) { | ||
serieNames = [name]; | ||
} else { | ||
serieNames = chromatogram.getSerieNames(); | ||
} | ||
let results = {}; | ||
@@ -381,3 +448,2 @@ serieNames.forEach(name => results[name] = []); | ||
for (let serieName of serieNames) { | ||
@@ -387,6 +453,6 @@ let serie = chromatogram.series[serieName]; | ||
case 1: | ||
results[serieName].push(integrate1D(time, serie, from, to, fromIndex, toIndex, options)); | ||
results[serieName].push(integrate1D(time, serie, from, to, fromIndex, toIndex, baseline)); | ||
break; | ||
case 2: | ||
results[serieName].push(integrate2D(time, serie, from, to, fromIndex, toIndex, options)); | ||
results[serieName].push(integrate2D(time, serie, from, to, fromIndex, toIndex, {slot})); | ||
break; | ||
@@ -483,3 +549,3 @@ default: | ||
let max = -1; | ||
let max$$1 = -1; | ||
let massList = new Array(massXYObject.x.length); | ||
@@ -492,4 +558,4 @@ for (let i = 0; i < massXYObject.x.length; ++i) { | ||
if (massXYObject.y[i] > max) { | ||
max = massXYObject.y[i]; | ||
if (massXYObject.y[i] > max$$1) { | ||
max$$1 = massXYObject.y[i]; | ||
} | ||
@@ -499,4 +565,4 @@ } | ||
// filters based in thresholdFactor | ||
max *= thresholdFactor; | ||
let filteredList = massList.filter((val) => val.y > max); | ||
max$$1 *= thresholdFactor; | ||
let filteredList = massList.filter((val) => val.y > max$$1); | ||
@@ -539,3 +605,3 @@ // filters based in maxNumberPeaks | ||
let massDictionary = {}; | ||
let max = -1; | ||
let max$$1 = -1; | ||
for (let j = peakList[i].left.index; j <= peakList[i].right.index; ++j) { | ||
@@ -553,4 +619,4 @@ for (let k = 0; k < sampleMS[j][0].length; ++k) { | ||
if (massDictionary[mass] > max) { | ||
max = massDictionary[mass]; | ||
if (massDictionary[mass] > max$$1) { | ||
max$$1 = massDictionary[mass]; | ||
} | ||
@@ -702,3 +768,3 @@ } | ||
const defaultOptions$1 = { | ||
const defaultOptions = { | ||
oddReference: true | ||
@@ -715,3 +781,3 @@ }; | ||
function applyLockMass(mf, options) { | ||
options = Object.assign({}, defaultOptions$1, options); | ||
options = Object.assign({}, defaultOptions, options); | ||
@@ -974,2 +1040,14 @@ // allows mf as string or array | ||
/** | ||
* Calculate bpc | ||
* @param {object} [options = {}] - Options object | ||
* @param {boolean} [options.force = false] - Force the calculation it it exists | ||
*/ | ||
calculateBpc(options = {}) { | ||
if (!this.getSerie('bpc') || options.force) { | ||
let bpc = calculateBpc(this); | ||
this.addSerie('bpc', bpc); | ||
} | ||
} | ||
/** | ||
* Calculates the table of Kovats indexes for the reference spectra | ||
@@ -1184,3 +1262,3 @@ * @param {object} [options = {}] - Options object | ||
for (let i = 0; i < sample.peaks.length; ++i) { | ||
let max = {similarity: -3}; | ||
let max$$1 = {similarity: -3}; | ||
let biggerCounter = 0; | ||
@@ -1190,4 +1268,4 @@ for (let j = 0; j < reference.peaks.length; ++j) { | ||
if (sim > options.similarityThreshold && sim > max.similarity) { | ||
max = { | ||
if (sim > options.similarityThreshold && sim > max$$1.similarity) { | ||
max$$1 = { | ||
similarity: sim, | ||
@@ -1203,5 +1281,5 @@ chrom1: reference.peaks[j], | ||
if (biggerCounter === 1) { | ||
similarityPeaks.chrom1[similarLen] = max.chrom1; | ||
similarityPeaks.chrom2[similarLen] = max.chrom2; | ||
similarityPeaks.similarity[similarLen++] = max.similarity; | ||
similarityPeaks.chrom1[similarLen] = max$$1.chrom1; | ||
similarityPeaks.chrom2[similarLen] = max$$1.chrom2; | ||
similarityPeaks.similarity[similarLen++] = max$$1.similarity; | ||
} | ||
@@ -1208,0 +1286,0 @@ } |
{ | ||
"name": "chromatography", | ||
"version": "2.0.6", | ||
"version": "2.1.0", | ||
"description": "Tools for storing, search and analize GC/MS spectra", | ||
@@ -12,3 +12,3 @@ "main": "lib/index.js", | ||
"scripts": { | ||
"build": "cheminfo build --root Chromatography", | ||
"build": "rollup -c && cheminfo build --root Chromatography", | ||
"build-doc": "cheminfo doc", | ||
@@ -44,2 +44,3 @@ "publish-doc": "cheminfo doc --publish", | ||
"babel-preset-env": "^1.5.2", | ||
"cheminfo-tools": "^1.16.2", | ||
"codecov": "^2.2.0", | ||
@@ -58,2 +59,3 @@ "documentation": "^4.0.0-rc.1", | ||
"jcampconverter": "^2.3.0", | ||
"ml-array-max": "^1.0.0", | ||
"ml-gsd": "^2.0.1", | ||
@@ -60,0 +62,0 @@ "ml-regression-polynomial": "^1.0.2", |
@@ -59,3 +59,9 @@ import {Chromatogram} from '..'; | ||
var result = chromato.getIntegrations([1.5, 5.5]); | ||
expect(result).toEqual({tic: [125]}); | ||
expect(result).toEqual({tic: [{ | ||
integral: 125, | ||
base: { | ||
start: {height: 0, time: 1.5}, | ||
end: {height: 0, time: 5.5} | ||
} | ||
}]}); | ||
}); |
@@ -5,3 +5,3 @@ import {readFileSync} from 'fs'; | ||
test('load JCAMP', async () => { | ||
test('load JCAMP', () => { | ||
const path = join(__dirname, '../data/jcamp/MixC8-C40_140630.JDX'); | ||
@@ -8,0 +8,0 @@ const jcamp = readFileSync(path, 'utf8'); |
@@ -17,1 +17,17 @@ const {fromText} = require('../..'); | ||
test('Parse a text with options', () => { | ||
const text = ` | ||
1,2,3 | ||
2,3,4 | ||
3,4,5 | ||
`; | ||
let newChromatogram = fromText(text, { | ||
xColumn: 1, | ||
yColumn: 2 | ||
}); | ||
expect(newChromatogram.getSerie('intensity').data.length).toEqual(3); | ||
expect(newChromatogram.times.length).toEqual(3); | ||
expect(newChromatogram.times).toEqual([2, 3, 4]); | ||
expect(newChromatogram.getSerieNames()).toEqual(['intensity']); | ||
}); |
@@ -6,3 +6,3 @@ import {readFileSync} from 'fs'; | ||
test('from a Diesel chromatogram', async () => { | ||
test('from a Diesel chromatogram', () => { | ||
const path = join(__dirname, 'data/jcamp/P064.JDX'); | ||
@@ -9,0 +9,0 @@ const jcamp = readFileSync(path, 'utf8'); |
@@ -28,3 +28,3 @@ import {readFileSync} from 'fs'; | ||
test('Non-in place', async () => { | ||
test('Non-in place', () => { | ||
const path = join(__dirname, 'data/jcamp/P064.JDX'); | ||
@@ -68,3 +68,3 @@ const jcamp = readFileSync(path, 'utf8'); | ||
test('In place', async () => { | ||
test('In place', () => { | ||
const path = join(__dirname, 'data/jcamp/P064.JDX'); | ||
@@ -71,0 +71,0 @@ const jcamp = readFileSync(path, 'utf8'); |
import {Chromatogram, spectraComparison, scaleAlignment} from '..'; | ||
import {lorentzian} from './data/examples'; | ||
test('Simple case', async () => { | ||
test('Simple case', () => { | ||
const size = 70; | ||
@@ -41,3 +41,3 @@ const peakX = 10; | ||
test('Quality and string', async () => { | ||
test('Quality and string', () => { | ||
const size = 70; | ||
@@ -44,0 +44,0 @@ const peakX = 10; |
@@ -1,4 +0,6 @@ | ||
import {integrate} from '../..'; | ||
import {integrate, Chromatogram} from '../..'; | ||
import {chromato} from '../data/examples'; | ||
var chrom = new Chromatogram([1, 2, 3, 4], {tic: [2, 4, 6, 8]}); | ||
test('Integrate a tic', () => { | ||
@@ -15,3 +17,9 @@ | ||
var result = integrate(chromato, [1.8, 5.5]); | ||
expect(result).toEqual({tic: [120.05]}); | ||
expect(result).toEqual({tic: [{ | ||
integral: 120.05, | ||
base: { | ||
start: {height: 0, time: 1.8}, | ||
end: {height: 0, time: 5.5} | ||
} | ||
}]}); | ||
@@ -39,1 +47,50 @@ // | ||
}); | ||
describe('Applies baseline correction', () => { | ||
it('without baseline', () => { | ||
var result = integrate(chrom, [1, 3], {name: 'tic', baseline: false}); | ||
expect(result).toEqual({tic: [{ | ||
integral: 8, | ||
base: { | ||
start: {height: 0, time: 1}, | ||
end: {height: 0, time: 3} | ||
} | ||
}]}); | ||
}); | ||
it('trapezoid baseline', () => { | ||
var result = integrate(chrom, [1, 3], {name: 'tic', baseline: 'trapezoid'}); | ||
expect(result).toEqual({tic: [{ | ||
integral: 0, | ||
base: { | ||
start: {height: 2, time: 1}, | ||
end: {height: 6, time: 3} | ||
} | ||
}]}); | ||
}); | ||
it('min baseline', () => { | ||
var result = integrate(chrom, [1, 3], {name: 'tic', baseline: 'min'}); | ||
expect(result).toEqual({tic: [{ | ||
integral: 4, | ||
base: { | ||
start: {height: 2, time: 1}, | ||
end: {height: 2, time: 3} | ||
} | ||
}]}); | ||
var other = new Chromatogram([1, 2, 3], {tic: [6, 4, 2]}); | ||
result = integrate(other, [1, 3], {name: 'tic', baseline: 'min'}); | ||
expect(result).toEqual({tic: [{ | ||
integral: 4, | ||
base: { | ||
start: {height: 2, time: 1}, | ||
end: {height: 2, time: 3} | ||
} | ||
}]}); | ||
}); | ||
it('error', () => { | ||
expect(() => integrate(chrom, [1, 3], {name: 'tic', baseline: 'bla'})).toThrow('Unknown baseline method "bla"'); | ||
}); | ||
}); |
@@ -6,3 +6,3 @@ import {readFileSync} from 'fs'; | ||
test('from a Diesel chromatogram', async () => { | ||
test('from a Diesel chromatogram', () => { | ||
const path = join(__dirname, 'data/jcamp/P064.JDX'); | ||
@@ -9,0 +9,0 @@ const jcamp = readFileSync(path, 'utf8'); |
@@ -7,2 +7,3 @@ import {rescaleTime} from './rescaleTime'; | ||
import {calculateTic} from './ms/calculateTic'; | ||
import {calculateBpc} from './ms/calculateBpc'; | ||
import {integrate} from './util/integrate'; | ||
@@ -196,2 +197,14 @@ import {getKovatsRescale} from './getKovatsRescale'; | ||
/** | ||
* Calculate bpc | ||
* @param {object} [options = {}] - Options object | ||
* @param {boolean} [options.force = false] - Force the calculation it it exists | ||
*/ | ||
calculateBpc(options = {}) { | ||
if (!this.getSerie('bpc') || options.force) { | ||
let bpc = calculateBpc(this); | ||
this.addSerie('bpc', bpc); | ||
} | ||
} | ||
/** | ||
* Calculates the table of Kovats indexes for the reference spectra | ||
@@ -198,0 +211,0 @@ * @param {object} [options = {}] - Options object |
@@ -5,6 +5,2 @@ import {getClosestTime} from './getClosestTime'; | ||
const defaultOptions = { | ||
slot: 1 | ||
}; | ||
/** | ||
@@ -21,6 +17,12 @@ * Returns a mass spectrum that is the integration of all the spectra in a specific range of time | ||
* @param {number} [options.slot = 2] - Define when 2 peaks will be combined | ||
* @param {string} [options.name] - Name of the serie to integrate, by default all the series are integrated | ||
* @param {string|boolean} [options.baseline] - Applies baseline correction | ||
* @return {{serieName: []}} | ||
*/ | ||
export function integrate(chromatogram, ranges, options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
export function integrate(chromatogram, ranges, options = {}) { | ||
const { | ||
slot = 1, | ||
name = false, | ||
baseline = false | ||
} = options; | ||
@@ -33,3 +35,8 @@ if (!Array.isArray(ranges)) throw new Error('fromTo must be an array of type [from,to]'); | ||
// by default we integrate all the series | ||
var serieNames = chromatogram.getSerieNames(); | ||
let serieNames; | ||
if (name) { | ||
serieNames = [name]; | ||
} else { | ||
serieNames = chromatogram.getSerieNames(); | ||
} | ||
let results = {}; | ||
@@ -44,3 +51,2 @@ serieNames.forEach(name => results[name] = []); | ||
for (let serieName of serieNames) { | ||
@@ -50,6 +56,6 @@ let serie = chromatogram.series[serieName]; | ||
case 1: | ||
results[serieName].push(integrate1D(time, serie, from, to, fromIndex, toIndex, options)); | ||
results[serieName].push(integrate1D(time, serie, from, to, fromIndex, toIndex, baseline)); | ||
break; | ||
case 2: | ||
results[serieName].push(integrate2D(time, serie, from, to, fromIndex, toIndex, options)); | ||
results[serieName].push(integrate2D(time, serie, from, to, fromIndex, toIndex, {slot})); | ||
break; | ||
@@ -56,0 +62,0 @@ default: |
@@ -1,2 +0,4 @@ | ||
export function integrate1D(time, serie, from, to, fromIndex, toIndex) { | ||
import {baselineCorrection} from './baselineCorrection'; | ||
export function integrate1D(time, serie, from, to, fromIndex, toIndex, baseline) { | ||
if (serie.dimension !== 1) throw new Error('The serie name is not of dimension 1'); | ||
@@ -6,2 +8,3 @@ if (!serie.data) return 0; | ||
let total = 0; | ||
let base = {}; | ||
for (let i = fromIndex; i < toIndex; i++) { | ||
@@ -13,2 +16,3 @@ let timeStart = time[i]; | ||
heightStart = serie.data[i] + (serie.data[i + 1] - serie.data[i]) * (from - timeStart) / (timeEnd - timeStart); | ||
base.start = {height: heightStart, time: from}; | ||
timeStart = from; | ||
@@ -19,3 +23,4 @@ } | ||
if (i === toIndex - 1) { | ||
heightEnd = serie.data[i] + (serie.data[i + 1] - serie.data[i]) * (timeEnd - to) / (timeEnd - timeStart); | ||
heightEnd = serie.data[i] + (serie.data[i + 1] - serie.data[i]) * (to - timeStart) / (timeEnd - timeStart); | ||
base.end = {height: heightEnd, time: to}; | ||
timeEnd = to; | ||
@@ -25,3 +30,14 @@ } | ||
} | ||
return total; | ||
if (baseline) { | ||
return baselineCorrection(total, base, baseline); | ||
} else { | ||
return { | ||
integral: total, | ||
base: { | ||
start: {height: 0, time: from}, | ||
end: {height: 0, time: to} | ||
} | ||
}; | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
23647131
65
5555
0
7
13
+ Addedml-array-max@^1.0.0