isotopic-distribution
Advanced tools
Comparing version 1.4.15 to 1.4.16
{ | ||
"name": "isotopic-distribution", | ||
"version": "1.4.15", | ||
"version": "1.4.16", | ||
"description": "Calculate the isotopic distribution of a molecular formula", | ||
"main": "src/index.js", | ||
"main": "lib/index.js", | ||
"module": "src/index.js", | ||
"files": [ | ||
"src" | ||
"src", | ||
"lib" | ||
], | ||
@@ -19,8 +21,8 @@ "repository": { | ||
}, | ||
"homepage": "https://github.com/cheminfo/mass-tools/tree/master/packages/isotopic-distribution#readme", | ||
"homepage": "https://github.com/cheminfo/mass-tools/tree/main/packages/isotopic-distribution#readme", | ||
"dependencies": { | ||
"chemical-elements": "^1.2.3", | ||
"mf-parser": "^1.4.7", | ||
"mf-utilities": "^1.4.1", | ||
"spectrum-generator": "^8.0.1" | ||
"chemical-elements": "^1.2.4", | ||
"mf-parser": "^1.4.8", | ||
"mf-utilities": "^1.4.2", | ||
"spectrum-generator": "^8.0.6" | ||
}, | ||
@@ -30,3 +32,3 @@ "devDependencies": { | ||
}, | ||
"gitHead": "09dc5f380182d586410e390df190c8d27101fc3e" | ||
"gitHead": "bd2c06e05f2196c5f9c6ff011cf3ef41e1b6a0f9" | ||
} |
@@ -15,5 +15,5 @@ # isotopic-distribution | ||
```js | ||
import library from 'isotopic-distribution'; | ||
const { IsotopicDistribution } = require('isotopic-distribution'); | ||
const result = library(args); | ||
const isotopicDistribution = new IsotopicDistribution('C10H20'); | ||
// result is ... | ||
@@ -20,0 +20,0 @@ ``` |
@@ -1,5 +0,3 @@ | ||
'use strict'; | ||
import { Distribution } from '../Distribution.js'; | ||
const Distribution = require('../Distribution.js'); | ||
describe('test distribution append', () => { | ||
@@ -6,0 +4,0 @@ it('should append one distribution to another', () => { |
@@ -1,20 +0,16 @@ | ||
'use strict'; | ||
import { Distribution } from '../Distribution.js'; | ||
const Distribution = require('../Distribution.js'); | ||
test('distribution closestPointX', () => { | ||
let distribution = new Distribution(); | ||
distribution.push({ x: 1, y: 2 }); | ||
distribution.push({ x: 2, y: 3 }); | ||
distribution.push({ x: 3, y: 3 }); | ||
distribution.push({ x: 4, y: 3 }); | ||
describe('test distribution closestPointX', () => { | ||
it('should yield the right point', () => { | ||
let dist = new Distribution(); | ||
dist.push({ x: 1, y: 2 }); | ||
dist.push({ x: 2, y: 3 }); | ||
dist.push({ x: 3, y: 3 }); | ||
dist.push({ x: 4, y: 3 }); | ||
expect(dist.closestPointX(2)).toStrictEqual({ x: 2, y: 3 }); | ||
expect(dist.closestPointX(0)).toStrictEqual({ x: 1, y: 2 }); | ||
expect(dist.closestPointX(2.1)).toStrictEqual({ x: 2, y: 3 }); | ||
expect(dist.closestPointX(1.9)).toStrictEqual({ x: 2, y: 3 }); | ||
expect(dist.closestPointX(5.1)).toStrictEqual({ x: 4, y: 3 }); | ||
expect(dist.closestPointX(4.9)).toStrictEqual({ x: 4, y: 3 }); | ||
}); | ||
expect(distribution.closestPointX(2)).toStrictEqual({ x: 2, y: 3 }); | ||
expect(distribution.closestPointX(0)).toStrictEqual({ x: 1, y: 2 }); | ||
expect(distribution.closestPointX(2.1)).toStrictEqual({ x: 2, y: 3 }); | ||
expect(distribution.closestPointX(1.9)).toStrictEqual({ x: 2, y: 3 }); | ||
expect(distribution.closestPointX(5.1)).toStrictEqual({ x: 4, y: 3 }); | ||
expect(distribution.closestPointX(4.9)).toStrictEqual({ x: 4, y: 3 }); | ||
}); |
@@ -1,5 +0,3 @@ | ||
'use strict'; | ||
import { IsotopicDistribution } from '../IsotopicDistribution.js'; | ||
const IsotopicDistribution = require('../IsotopicDistribution.js'); | ||
describe('test isotopicDistribution', () => { | ||
@@ -6,0 +4,0 @@ it('create distribution of C1 with default options', () => { |
@@ -1,9 +0,7 @@ | ||
'use strict'; | ||
import { toBeDeepCloseTo } from 'jest-matcher-deep-close-to'; | ||
const { toBeDeepCloseTo } = require('jest-matcher-deep-close-to'); | ||
import { IsotopicDistribution } from '..'; | ||
expect.extend({ toBeDeepCloseTo }); | ||
const IsotopicDistribution = require('../IsotopicDistribution.js'); | ||
describe('isotopicDistribution with composition', () => { | ||
@@ -10,0 +8,0 @@ it('CN', () => { |
@@ -1,5 +0,3 @@ | ||
'use strict'; | ||
import { IsotopicDistribution } from '..'; | ||
const IsotopicDistribution = require('../IsotopicDistribution.js'); | ||
describe('test isotopicDistribution', () => { | ||
@@ -6,0 +4,0 @@ it('create distribution of CH0', () => { |
@@ -1,5 +0,3 @@ | ||
'use strict'; | ||
import { Distribution } from '../Distribution.js'; | ||
const Distribution = require('../Distribution.js'); | ||
describe('test distribution multiply', () => { | ||
@@ -6,0 +4,0 @@ it('should yield the product', () => { |
@@ -1,13 +0,11 @@ | ||
'use strict'; | ||
import { Distribution } from '../Distribution.js'; | ||
const Distribution = require('../Distribution.js'); | ||
describe('test distribution normalize', () => { | ||
it('should yield the product', () => { | ||
let dist = new Distribution(); | ||
dist.push({ x: 1, y: 2 }); | ||
dist.push({ x: 2, y: 3 }); | ||
dist.normalize(); | ||
let distribution = new Distribution(); | ||
distribution.push({ x: 1, y: 2 }); | ||
distribution.push({ x: 2, y: 3 }); | ||
distribution.normalize(); | ||
expect(dist.array).toStrictEqual([ | ||
expect(distribution.array).toStrictEqual([ | ||
{ x: 1, y: 0.4 }, | ||
@@ -14,0 +12,0 @@ { x: 2, y: 0.6 }, |
@@ -1,12 +0,10 @@ | ||
'use strict'; | ||
import { Distribution } from '../Distribution.js'; | ||
const Distribution = require('../Distribution.js'); | ||
describe('test distribution power', () => { | ||
it('power 2', () => { | ||
let dist = new Distribution(); | ||
dist.push({ x: 1, y: 2 }); | ||
dist.push({ x: 2, y: 3 }); | ||
dist.power(2); | ||
expect(dist.array).toStrictEqual([ | ||
let distribution = new Distribution(); | ||
distribution.push({ x: 1, y: 2 }); | ||
distribution.push({ x: 2, y: 3 }); | ||
distribution.power(2); | ||
expect(distribution.array).toStrictEqual([ | ||
{ x: 2, y: 4 }, | ||
@@ -19,14 +17,14 @@ { x: 3, y: 12 }, | ||
it('power 3 - 1 peak', () => { | ||
let dist = new Distribution(); | ||
dist.push({ x: 1, y: 1 }); | ||
dist.power(3); | ||
expect(dist.array).toStrictEqual([{ x: 3, y: 1 }]); | ||
let distribution = new Distribution(); | ||
distribution.push({ x: 1, y: 1 }); | ||
distribution.power(3); | ||
expect(distribution.array).toStrictEqual([{ x: 3, y: 1 }]); | ||
}); | ||
it('power 3 - 2 peaks', () => { | ||
let dist = new Distribution(); | ||
dist.push({ x: 1, y: 1 }); | ||
dist.push({ x: 2, y: 1 }); | ||
dist.power(3); | ||
expect(dist.array).toStrictEqual([ | ||
let distribution = new Distribution(); | ||
distribution.push({ x: 1, y: 1 }); | ||
distribution.push({ x: 2, y: 1 }); | ||
distribution.power(3); | ||
expect(distribution.array).toStrictEqual([ | ||
{ x: 3, y: 1 }, | ||
@@ -40,16 +38,16 @@ { x: 4, y: 3 }, | ||
it('power 1000 - 2 peaks', () => { | ||
let dist = new Distribution(); | ||
dist.push({ x: 1, y: 1 }); | ||
dist.push({ x: 2, y: 1 }); | ||
dist.power(1000); | ||
expect(dist.array).toHaveLength(1001); | ||
expect(dist.array[1]).toStrictEqual({ x: 1001, y: 1000 }); | ||
let distribution = new Distribution(); | ||
distribution.push({ x: 1, y: 1 }); | ||
distribution.push({ x: 2, y: 1 }); | ||
distribution.power(1000); | ||
expect(distribution.array).toHaveLength(1001); | ||
expect(distribution.array[1]).toStrictEqual({ x: 1001, y: 1000 }); | ||
}); | ||
it('power 100000 - 10 peaks', () => { | ||
let dist = new Distribution(); | ||
dist.push({ x: 1, y: 0.5 }); | ||
dist.push({ x: 2, y: 0.5 }); | ||
dist.power(100000); | ||
let sum = dist.array.reduce((s, a) => s + a.y, 0); | ||
let distribution = new Distribution(); | ||
distribution.push({ x: 1, y: 0.5 }); | ||
distribution.push({ x: 2, y: 0.5 }); | ||
distribution.power(100000); | ||
let sum = distribution.array.reduce((s, a) => s + a.y, 0); | ||
expect(sum).toBeGreaterThan(0.99); | ||
@@ -56,0 +54,0 @@ expect(sum).toBeLessThan(1); |
@@ -1,12 +0,10 @@ | ||
'use strict'; | ||
import { Distribution } from '../Distribution.js'; | ||
const Distribution = require('../Distribution.js'); | ||
describe('test array-object-xy square', () => { | ||
it('should yield the product', () => { | ||
let dist = new Distribution(); | ||
dist.push({ x: 1, y: 2 }); | ||
dist.push({ x: 2, y: 3 }); | ||
dist.square(); | ||
expect(dist.array).toStrictEqual([ | ||
let distribution = new Distribution(); | ||
distribution.push({ x: 1, y: 2 }); | ||
distribution.push({ x: 2, y: 3 }); | ||
distribution.square(); | ||
expect(distribution.array).toStrictEqual([ | ||
{ x: 2, y: 4 }, | ||
@@ -13,0 +11,0 @@ { x: 3, y: 12 }, |
@@ -1,15 +0,13 @@ | ||
'use strict'; | ||
import { Distribution } from '../Distribution.js'; | ||
const Distribution = require('../Distribution.js'); | ||
describe('test distribution topY', () => { | ||
it('create array', () => { | ||
let dist = new Distribution(); | ||
dist.push({ x: 1, y: 2 }); | ||
dist.push({ x: 2, y: 3 }); | ||
dist.push({ x: 2, y: 1 }); | ||
dist.push({ x: 2, y: 4 }); | ||
dist.topY(2); | ||
let distribution = new Distribution(); | ||
distribution.push({ x: 1, y: 2 }); | ||
distribution.push({ x: 2, y: 3 }); | ||
distribution.push({ x: 2, y: 1 }); | ||
distribution.push({ x: 2, y: 4 }); | ||
distribution.topY(2); | ||
expect(dist.array).toStrictEqual([ | ||
expect(distribution.array).toStrictEqual([ | ||
{ x: 2, y: 4 }, | ||
@@ -16,0 +14,0 @@ { x: 2, y: 3 }, |
@@ -1,4 +0,10 @@ | ||
'use strict'; | ||
import { closestPointX } from './utils/closestPointX.js'; | ||
import { joinX } from './utils/joinX.js'; | ||
import { multiply } from './utils/multiply.js'; | ||
import { power } from './utils/power.js'; | ||
class Distribution { | ||
/** | ||
* Internal class to deal with isotopic distribution calculations | ||
*/ | ||
export class Distribution { | ||
constructor(array) { | ||
@@ -47,58 +53,109 @@ if (Array.isArray(array)) { | ||
} | ||
} | ||
Distribution.prototype.multiplyY = function multiplyY(value) { | ||
this.array.forEach((item) => (item.y *= value)); | ||
}; | ||
multiplyY(value) { | ||
this.array.forEach((item) => (item.y *= value)); | ||
} | ||
Distribution.prototype.setArray = function setArray(array) { | ||
this.array = array; | ||
this.xSorted = false; | ||
this.ySorted = false; | ||
}; | ||
setArray(array) { | ||
this.array = array; | ||
this.xSorted = false; | ||
this.ySorted = false; | ||
} | ||
Distribution.prototype.move = function move(other) { | ||
this.xSorted = other.xSorted; | ||
this.ySorted = other.ySorted; | ||
this.array = other.array; | ||
}; | ||
move(other) { | ||
this.xSorted = other.xSorted; | ||
this.ySorted = other.ySorted; | ||
this.array = other.array; | ||
} | ||
Distribution.prototype.copy = function copy() { | ||
let distCopy = new this.constructor(); | ||
distCopy.xSorted = this.xSorted; | ||
distCopy.ySorted = this.ySorted; | ||
distCopy.array = JSON.parse(JSON.stringify(this.array)); | ||
return distCopy; | ||
}; | ||
push(point) { | ||
this.array.push(point); | ||
Distribution.prototype.push = function push(point) { | ||
this.array.push(point); | ||
this.xSorted = false; | ||
this.ySorted = false; | ||
} | ||
this.xSorted = false; | ||
this.ySorted = false; | ||
}; | ||
sortX() { | ||
this.ySorted = false; | ||
if (this.xSorted) return this; | ||
this.array.sort((a, b) => a.x - b.x); | ||
this.xSorted = true; | ||
return this; | ||
} | ||
/** | ||
* Appen another distribution to the current distribution | ||
* @param {*} distribution | ||
*/ | ||
Distribution.prototype.append = function append(distribution) { | ||
for (let item of distribution.array) { | ||
this.array.push(item); | ||
sortY() { | ||
this.xSorted = false; | ||
if (this.ySorted) return this; | ||
this.array.sort((a, b) => b.y - a.y); | ||
this.ySorted = true; | ||
return this; | ||
} | ||
this.xSorted = false; | ||
this.ySorted = false; | ||
}; | ||
Distribution.prototype.sortX = require('./utils/sortX.js'); | ||
Distribution.prototype.sortY = require('./utils/sortY.js'); | ||
Distribution.prototype.joinX = require('./utils/joinX.js'); | ||
Distribution.prototype.topY = require('./utils/topY.js'); | ||
Distribution.prototype.maxToOne = require('./utils/maxToOne.js'); | ||
Distribution.prototype.multiply = require('./utils/multiply.js'); | ||
Distribution.prototype.square = require('./utils/square.js'); | ||
Distribution.prototype.power = require('./utils/power.js'); | ||
Distribution.prototype.normalize = require('./utils/normalize.js'); | ||
Distribution.prototype.closestPointX = require('./utils/closestPointX.js'); | ||
normalize() { | ||
let sum = 0; | ||
for (let item of this.array) { | ||
sum += item.y; | ||
} | ||
for (let item of this.array) { | ||
item.y /= sum; | ||
} | ||
return this; | ||
} | ||
module.exports = Distribution; | ||
topY(limit) { | ||
if (!limit) return this; | ||
if (this.array.length <= limit) return this; | ||
this.sortY(); | ||
this.array.splice(limit); | ||
return this; | ||
} | ||
square(options = {}) { | ||
return this.multiply(this, options); | ||
} | ||
multiply(b, options) { | ||
return multiply(this, b, options); | ||
} | ||
power(p, options) { | ||
return power(this, p, options); | ||
} | ||
copy() { | ||
let distCopy = new Distribution(); | ||
distCopy.xSorted = this.xSorted; | ||
distCopy.ySorted = this.ySorted; | ||
distCopy.array = JSON.parse(JSON.stringify(this.array)); | ||
return distCopy; | ||
} | ||
maxToOne() { | ||
if (this.array.length === 0) return this; | ||
let currentMax = this.array[0].y; | ||
for (let item of this.array) { | ||
if (item.y > currentMax) currentMax = item.y; | ||
} | ||
for (let item of this.array) { | ||
item.y /= currentMax; | ||
} | ||
return this; | ||
} | ||
joinX(threshold) { | ||
return joinX(this, threshold); | ||
} | ||
append(distribution) { | ||
for (let item of distribution.array) { | ||
this.array.push(item); | ||
} | ||
this.xSorted = false; | ||
this.ySorted = false; | ||
} | ||
closestPointX(target) { | ||
this.sortX(); | ||
return closestPointX(this.array, target); | ||
} | ||
} |
@@ -1,5 +0,1 @@ | ||
'use strict'; | ||
const IsotopicDistribution = require('./IsotopicDistribution'); | ||
module.exports = IsotopicDistribution; | ||
export * from './IsotopicDistribution'; |
@@ -1,12 +0,9 @@ | ||
'use strict'; | ||
import { ELECTRON_MASS } from 'chemical-elements'; | ||
import { MF } from 'mf-parser'; | ||
import { preprocessIonizations, getMsInfo } from 'mf-utilities'; | ||
import { SpectrumGenerator } from 'spectrum-generator'; | ||
const ELECTRON_MASS = require('chemical-elements').ELECTRON_MASS; | ||
const MF = require('mf-parser').MF; | ||
const getMsInfo = require('mf-utilities/src/getMsInfo'); | ||
const preprocessIonizations = require('mf-utilities/src/preprocessIonizations'); | ||
const SpectrumGenerator = require('spectrum-generator').SpectrumGenerator; | ||
import { Distribution } from './Distribution'; | ||
import { getDerivedCompositionInfo } from './utils/getDerivedCompositionInfo'; | ||
const Distribution = require('./Distribution'); | ||
const getDerivedCompositionInfo = require('./utils/getDerivedCompositionInfo'); | ||
const MINIMAL_FWHM = 1e-8; | ||
@@ -21,3 +18,6 @@ | ||
class IsotopicDistribution { | ||
/** | ||
* A class that allows to manage isotopic distribution | ||
*/ | ||
export class IsotopicDistribution { | ||
/** | ||
@@ -340,3 +340,1 @@ * Class that manage isotopic distribution | ||
} | ||
module.exports = IsotopicDistribution; |
@@ -1,5 +0,3 @@ | ||
'use strict'; | ||
const { getDerivedCompositionInfo } = require('../getDerivedCompositionInfo'); | ||
const getDerivedCompositionInfo = require('../getDerivedCompositionInfo'); | ||
test('getDerivedCompositionInfo', () => { | ||
@@ -6,0 +4,0 @@ const data = { |
@@ -1,32 +0,25 @@ | ||
'use strict'; | ||
module.exports = function closestPointX(target) { | ||
this.sortX(); | ||
export function closestPointX(array, target) { | ||
let low = 0; | ||
let high = this.array.length - 1; | ||
let high = array.length - 1; | ||
let middle = 0; | ||
while (high - low > 1) { | ||
middle = low + ((high - low) >> 1); | ||
if (this.array[middle].x < target) { | ||
if (array[middle].x < target) { | ||
low = middle; | ||
} else if (this.array[middle].x > target) { | ||
} else if (array[middle].x > target) { | ||
high = middle; | ||
} else { | ||
return this.array[middle]; | ||
return array[middle]; | ||
} | ||
} | ||
if (low < this.array.length - 1) { | ||
if ( | ||
Math.abs(target - this.array[low].x) < | ||
Math.abs(this.array[low + 1].x - target) | ||
) { | ||
return this.array[low]; | ||
if (low < array.length - 1) { | ||
if (Math.abs(target - array[low].x) < Math.abs(array[low + 1].x - target)) { | ||
return array[low]; | ||
} else { | ||
return this.array[low + 1]; | ||
return array[low + 1]; | ||
} | ||
} else { | ||
return this.array[low]; | ||
return array[low]; | ||
} | ||
}; | ||
} |
@@ -1,7 +0,5 @@ | ||
'use strict'; | ||
import { stableIsotopesObject } from 'chemical-elements'; | ||
import { subscript, superscript } from 'mf-parser'; | ||
const { stableIsotopesObject } = require('chemical-elements'); | ||
const { subscript, superscript } = require('mf-parser'); | ||
function getDerivedCompositionInfo(composition) { | ||
export function getDerivedCompositionInfo(composition) { | ||
const shortComposition = {}; | ||
@@ -33,3 +31,1 @@ let label = ''; | ||
} | ||
module.exports = getDerivedCompositionInfo; |
@@ -1,3 +0,1 @@ | ||
'use strict'; | ||
/** | ||
@@ -7,10 +5,10 @@ * Join x values if there are similar | ||
module.exports = function joinX(threshold = Number.EPSILON) { | ||
export function joinX(self, threshold = Number.EPSILON) { | ||
// when we join we will use the center of mass | ||
if (this.array.length === 0) return []; | ||
this.sortX(); | ||
let current = this.array[0]; | ||
if (self.array.length === 0) return []; | ||
self.sortX(); | ||
let current = self.array[0]; | ||
let result = [current]; | ||
for (let i = 1; i < this.array.length; i++) { | ||
const item = this.array[i]; | ||
for (let i = 1; i < self.array.length; i++) { | ||
const item = self.array[i]; | ||
if (item.x - current.x <= threshold) { | ||
@@ -30,5 +28,5 @@ // weighted sum | ||
} | ||
this.array = result; | ||
this.ySorted = false; | ||
return this; | ||
}; | ||
self.array = result; | ||
self.ySorted = false; | ||
return self; | ||
} |
@@ -1,3 +0,1 @@ | ||
'use strict'; | ||
/** | ||
@@ -7,3 +5,3 @@ * Sum of Y to 1 | ||
module.exports = function maxToOne() { | ||
export function maxToOne() { | ||
if (this.array.length === 0) return this; | ||
@@ -18,2 +16,2 @@ let currentMax = this.array[0].y; | ||
return this; | ||
}; | ||
} |
@@ -1,11 +0,9 @@ | ||
'use strict'; | ||
module.exports = function multiply(b, options = {}) { | ||
export function multiply(a, b, options = {}) { | ||
const { minY = 1e-8, maxLines = 5000, deltaX = 1e-2 } = options; | ||
const result = new this.constructor(); | ||
const result = new a.constructor(); | ||
this.sortY(); | ||
a.sortY(); | ||
b.sortY(); | ||
for (let entryA of this.array) { | ||
for (let entryA of a.array) { | ||
for (let entryB of b.array) { | ||
@@ -29,5 +27,5 @@ let y = entryA.y * entryB.y; | ||
result.topY(maxLines); | ||
this.move(result); | ||
return this; | ||
}; | ||
a.move(result); | ||
return a; | ||
} | ||
@@ -34,0 +32,0 @@ function calculateComposition(entryA, entryB) { |
@@ -1,17 +0,15 @@ | ||
'use strict'; | ||
// https://en.wikipedia.org/wiki/Exponentiation_by_squaring | ||
module.exports = function power(p, options = {}) { | ||
export function power(a, p, options = {}) { | ||
if (p <= 0) throw new Error('power must be larger than 0'); | ||
if (p === 1) return this; | ||
if (p === 1) return a; | ||
if (p === 2) { | ||
return this.square(); | ||
return a.square(); | ||
} | ||
p--; | ||
let base = this.copy(); // linear time | ||
let base = a.copy(); // linear time | ||
while (p !== 0) { | ||
if ((p & 1) !== 0) { | ||
this.multiply(base, options); // executed <= log2(p) times | ||
a.multiply(base, options); // executed <= log2(p) times | ||
} | ||
@@ -22,3 +20,3 @@ p >>= 1; | ||
return this; | ||
}; | ||
return a; | ||
} |
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
68129
1936
26
Updatedchemical-elements@^1.2.4
Updatedmf-parser@^1.4.8
Updatedmf-utilities@^1.4.2
Updatedspectrum-generator@^8.0.6