Comparing version 0.9.1 to 0.12.0
{ | ||
"name": "mf-finder", | ||
"version": "0.9.1", | ||
"version": "0.12.0", | ||
"description": "Find a molecular formula from a monoisotopic mass", | ||
@@ -21,8 +21,9 @@ "main": "src/index.js", | ||
"dependencies": { | ||
"atom-sorter": "^0.9.1", | ||
"chemical-elements": "^0.9.1", | ||
"mf-parser": "^0.9.1", | ||
"mf-utilities": "^0.9.1", | ||
"atom-sorter": "^0.12.0", | ||
"chemical-elements": "^0.12.0", | ||
"mf-parser": "^0.12.0", | ||
"mf-utilities": "^0.12.0", | ||
"molecular-formula": "^1.1.0" | ||
} | ||
}, | ||
"gitHead": "aa2e6571c5f7121dda616b7d6920b7a653a8f9c7" | ||
} |
@@ -10,3 +10,3 @@ 'use strict'; | ||
precision: 1e5, | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -20,3 +20,3 @@ expect(result.mfs).toHaveLength(1); | ||
precision: 1e5, | ||
ionizations: 'H+' | ||
ionizations: 'H+', | ||
}); | ||
@@ -31,7 +31,7 @@ expect(result.mfs).toHaveLength(1); | ||
ms: { | ||
delta: 1.00727645232093, | ||
delta: -1.00727645232093, | ||
em: 25.00727645232093, | ||
ppm: 41969.85218003875, | ||
charge: 1 | ||
} | ||
ppm: -40279.33446656661, | ||
charge: 1, | ||
}, | ||
}); | ||
@@ -44,3 +44,3 @@ }); | ||
precision: 1e6, | ||
ionizations: 'H+' | ||
ionizations: 'H+', | ||
}); | ||
@@ -54,3 +54,3 @@ expect(result.mfs).toHaveLength(2); | ||
precision: 1e6, | ||
ionizations: 'H++' | ||
ionizations: 'H++', | ||
}); | ||
@@ -65,6 +65,6 @@ expect(result.mfs[1]).toMatchObject({ | ||
em: 6.50336393620593, | ||
delta: -17.49663606379407, | ||
delta: 17.49663606379407, | ||
charge: 2, | ||
ppm: 729026.5026580864 | ||
} | ||
ppm: 2690397.8057241603, | ||
}, | ||
}); | ||
@@ -79,3 +79,3 @@ | ||
precision: 1e5, | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -94,4 +94,4 @@ expect(result.mfs).toHaveLength(2); | ||
min: 0, | ||
max: 1 | ||
} | ||
max: 1, | ||
}, | ||
}); | ||
@@ -110,4 +110,4 @@ expect(result.mfs).toHaveLength(2); | ||
max: 1, | ||
onlyInteger: true | ||
} | ||
onlyInteger: true, | ||
}, | ||
}); | ||
@@ -123,6 +123,6 @@ expect(result.mfs).toHaveLength(1); | ||
{ mf: 'H', min: 0, max: 1 }, | ||
{ mf: 'S', min: 0, max: 100 } | ||
{ mf: 'S', min: 0, max: 100 }, | ||
], | ||
precision: 1e5, | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -138,3 +138,3 @@ expect(result.mfs).toHaveLength(2); | ||
precision: 1e5, | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -146,2 +146,12 @@ expect(result.mfs).toHaveLength(2); | ||
it('simple combinations for polymers', () => { | ||
let result = findMFs(92.99814, { | ||
ranges: '(CH2)0-10NOCl', | ||
precision: 1e4, | ||
allowNeutral: true, | ||
}); | ||
expect(result.mfs).toHaveLength(1); | ||
expect(result.mfs[0].mf).toBe('((CH2))2(NOCl)'); | ||
}); | ||
it('simple combinations from string ranges with ionizations', () => { | ||
@@ -152,6 +162,6 @@ let result = findMFs(12, { | ||
{ mf: 'H', min: 0, max: 1 }, | ||
{ mf: 'H+', min: 0, max: 2 } | ||
{ mf: 'H+', min: 0, max: 2 }, | ||
], | ||
precision: 1e5, | ||
ionizations: 'H+, H++' | ||
ionizations: 'H+, H++', | ||
}); | ||
@@ -167,6 +177,6 @@ expect(result.mfs).toHaveLength(4); | ||
{ mf: 'N', min: 0, max: 100 }, | ||
{ mf: 'S', min: 0, max: 100 } | ||
{ mf: 'S', min: 0, max: 100 }, | ||
], | ||
precision: 1e4, | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -181,6 +191,6 @@ expect(result.mfs).toHaveLength(0); | ||
{ mf: 'H', min: 0, max: 100 }, | ||
{ mf: 'S', min: 0, max: 100 } | ||
{ mf: 'S', min: 0, max: 100 }, | ||
], | ||
precision: 1000, | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -197,6 +207,6 @@ expect(result.info.numberResults).toBe(1); | ||
{ mf: 'H', min: 0, max: 100 }, | ||
{ mf: 'S', min: 0, max: 100 } | ||
{ mf: 'S', min: 0, max: 100 }, | ||
], | ||
precision: 10000, | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -214,3 +224,3 @@ expect(result.info.numberResults).toBe(3); | ||
precision: 1, | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -230,6 +240,6 @@ expect(result.info.numberMFEvaluated).toBeLessThan(50); | ||
{ mf: 'N', min: 0, max: 100 }, | ||
{ mf: 'O', min: 0, max: 100 } | ||
{ mf: 'O', min: 0, max: 100 }, | ||
], | ||
precision: 0.0001, | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -249,6 +259,6 @@ expect(result.info.numberMFEvaluated).toBeLessThan(500000); | ||
{ mf: 'N', min: 0, max: 10 }, | ||
{ mf: 'O', min: 0, max: 10 } | ||
{ mf: 'O', min: 0, max: 10 }, | ||
], | ||
precision: 1, | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -261,3 +271,3 @@ expect(result.mfs[0].mf).toBe('C88H5N3O4S'); | ||
ranges: [{ mf: 'C', min: 0, max: 2 }, { mf: 'H+', min: 0, max: 2 }], | ||
precision: 1e4 | ||
precision: 1e4, | ||
}); | ||
@@ -270,3 +280,3 @@ expect(result.mfs).toHaveLength(0); | ||
ranges: [{ mf: 'C', min: 0, max: 2 }, { mf: 'C+', min: 0, max: 2 }], | ||
precision: 1e5 | ||
precision: 1e5, | ||
}); | ||
@@ -283,5 +293,5 @@ expect(result.mfs).toHaveLength(2); | ||
{ mf: 'C+', min: 0, max: 2 }, | ||
{ mf: 'S+', min: 0, max: 2 } | ||
{ mf: 'S+', min: 0, max: 2 }, | ||
], | ||
precision: 1e5 | ||
precision: 1e5, | ||
}); | ||
@@ -297,7 +307,7 @@ | ||
{ mf: 'C+', min: 0, max: 2 }, | ||
{ mf: 'S+', min: 0, max: 2 } | ||
{ mf: 'S+', min: 0, max: 2 }, | ||
], | ||
precision: 1e5, | ||
maxCharge: 1, | ||
minCharge: 1 | ||
minCharge: 1, | ||
}); | ||
@@ -311,3 +321,3 @@ expect(result.mfs).toHaveLength(1); | ||
ranges: [{ mf: 'C', min: 1, max: 1 }], | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -321,3 +331,3 @@ expect(result.mfs).toHaveLength(1); | ||
ranges: [{ mf: 'C', min: 0, max: 100 }, { mf: 'H', min: 0, max: 100 }], | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -332,3 +342,3 @@ expect(result.mfs).toHaveLength(1); | ||
precision: 10000, | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -341,3 +351,3 @@ expect(result.mfs).toHaveLength(3); | ||
ranges: [{ mf: 'C+', min: 1, max: 2 }], | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -344,0 +354,0 @@ expect(result.mfs).toHaveLength(2); |
@@ -13,3 +13,3 @@ 'use strict'; | ||
{ mf: 'Me', min: 0, max: 1 }, | ||
{ mf: 'Ca++', min: 0, max: 1 } | ||
{ mf: 'Ca++', min: 0, max: 1 }, | ||
]); | ||
@@ -22,3 +22,3 @@ expect(Array.isArray(possibilities)).toBe(true); | ||
charge: 1, | ||
unsaturation: -2 | ||
unsaturation: -2, | ||
}); | ||
@@ -32,5 +32,4 @@ }); | ||
{ mf: 'Cl(-)', min: 0, max: 2 }, | ||
{ mf: '(C-1H)2', min: 0, max: 2 } | ||
{ mf: '(C-1H)2', min: 0, max: 2 }, | ||
]); | ||
expect(Array.isArray(possibilities)).toBe(true); | ||
@@ -41,3 +40,3 @@ expect(possibilities[0]).toMatchObject({ | ||
minInnerCharge: -2, | ||
maxInnerCharge: 2 | ||
maxInnerCharge: 2, | ||
}); | ||
@@ -49,10 +48,23 @@ }); | ||
expect(Array.isArray(possibilities)).toBe(true); | ||
expect(possibilities).toHaveLength(4); | ||
expect(possibilities).toHaveLength(3); | ||
expect(possibilities[0]).toMatchObject({ | ||
minCharge: 0, | ||
maxCharge: 0, | ||
originalMinCount: 2, | ||
originalMaxCount: 2 | ||
originalMinCount: 1, | ||
originalMaxCount: 1, | ||
}); | ||
}); | ||
it('check a string polymer kind', () => { | ||
let possibilities = preprocessRanges('ClBr2(CH2)0-2NO'); | ||
expect(Array.isArray(possibilities)).toBe(true); | ||
expect(possibilities).toHaveLength(2); | ||
expect(possibilities[0]).toMatchObject({ | ||
mf: 'ClBr2NO', | ||
minCharge: 0, | ||
maxCharge: 0, | ||
originalMinCount: 1, | ||
originalMaxCount: 1, | ||
}); | ||
}); | ||
}); |
@@ -20,3 +20,3 @@ 'use strict'; | ||
{ mf: 'H+', min: 0, max: 2 }, | ||
{ mf: 'O', min: 0, max: 0 } | ||
{ mf: 'O', min: 0, max: 0 }, | ||
]); | ||
@@ -26,3 +26,3 @@ let cache = new TargetMassCache(100, possibilities); | ||
minCharge: 0, | ||
maxCharge: 2 | ||
maxCharge: 2, | ||
}); | ||
@@ -35,3 +35,3 @@ }); | ||
minCharge: -1, | ||
maxCharge: 2 | ||
maxCharge: 2, | ||
}); | ||
@@ -48,3 +48,3 @@ expect(cache.minCharge).toBe(-1); | ||
precision: 1000, | ||
allowNeutral: true | ||
allowNeutral: true, | ||
}); | ||
@@ -54,3 +54,3 @@ expect(cache).toMatchObject({ | ||
maxCharge: 0, | ||
data: [{ charge: 0, minMass: 99.9, maxMass: 100.1 }] | ||
data: [{ charge: 0, minMass: 99.9, maxMass: 100.1 }], | ||
}); | ||
@@ -64,3 +64,3 @@ }); | ||
maxCharge: 2, | ||
precision: 1000 | ||
precision: 1000, | ||
}); | ||
@@ -74,7 +74,7 @@ expect(cache).toMatchObject({ | ||
minMass: Number.MAX_SAFE_INTEGER, | ||
maxMass: Number.MIN_SAFE_INTEGER | ||
maxMass: Number.MIN_SAFE_INTEGER, | ||
}, | ||
{ charge: 1, minMass: 99.90054857990907, maxMass: 100.10054857990906 }, | ||
{ charge: 2, minMass: 199.80109715981814, maxMass: 200.20109715981812 } | ||
] | ||
{ charge: 2, minMass: 199.80109715981814, maxMass: 200.20109715981812 }, | ||
], | ||
}); | ||
@@ -89,3 +89,3 @@ }); | ||
allowNeutral: false, | ||
precision: 1e6 | ||
precision: 1e6, | ||
}); | ||
@@ -100,6 +100,6 @@ expect(cache).toMatchObject({ | ||
minMass: Number.MAX_SAFE_INTEGER, | ||
maxMass: Number.MIN_SAFE_INTEGER | ||
maxMass: Number.MIN_SAFE_INTEGER, | ||
}, | ||
{ charge: 1, minMass: 0.00054857990907, maxMass: 200.00054857990906 } | ||
] | ||
{ charge: 1, minMass: 0.00054857990907, maxMass: 200.00054857990906 }, | ||
], | ||
}); | ||
@@ -115,3 +115,3 @@ }); | ||
allowNeutral: false, | ||
precision: 1e6 | ||
precision: 1e6, | ||
}); | ||
@@ -125,8 +125,8 @@ expect(cache).toMatchObject({ | ||
minMass: Number.MAX_SAFE_INTEGER, | ||
maxMass: Number.MIN_SAFE_INTEGER | ||
maxMass: Number.MIN_SAFE_INTEGER, | ||
}, | ||
{ charge: 1, minMass: 0.00054857990907, maxMass: 200.00054857990906 } | ||
] | ||
{ charge: 1, minMass: 0.00054857990907, maxMass: 200.00054857990906 }, | ||
], | ||
}); | ||
}); | ||
}); |
@@ -20,3 +20,3 @@ 'use strict'; | ||
module.exports = function findMF(targetMass, options = {}) { | ||
module.exports = function (targetMass, options = {}) { | ||
const { | ||
@@ -32,4 +32,4 @@ minCharge = Number.MIN_SAFE_INTEGER, | ||
{ mf: 'O', min: 0, max: 100 }, | ||
{ mf: 'N', min: 0, max: 100 } | ||
] | ||
{ mf: 'N', min: 0, max: 100 }, | ||
], | ||
} = options; | ||
@@ -56,4 +56,4 @@ | ||
numberMFEvaluated: 0, | ||
numberResults: 0 | ||
} | ||
numberResults: 0, | ||
}, | ||
}; | ||
@@ -66,5 +66,5 @@ let orderMapping = []; // used to sort the atoms | ||
let currentIonization = { | ||
currentMonoisotopicMass: ionization.em, | ||
currentMonoisotopicMass: ionization.em || 0, | ||
currentCharge: ionization.charge, | ||
currentUnsaturation: 0 // we don't take into account the unsaturation of the ionization agent | ||
currentUnsaturation: 0, // we don't take into account the unsaturation of the ionization agent | ||
}; | ||
@@ -80,3 +80,3 @@ // if (DEBUG) console.log('new ionization', ionization.mf, ionization.em, ionization.charge); | ||
possibilities, | ||
Object.assign({}, options, { charge: ionization.charge }) | ||
Object.assign({}, options, { charge: ionization.charge }), | ||
); | ||
@@ -100,3 +100,3 @@ | ||
throw Error( | ||
`Iteration number is over the current maximum of: ${maxIterations}` | ||
`Iteration number is over the current maximum of: ${maxIterations}`, | ||
); | ||
@@ -141,4 +141,4 @@ } | ||
ionization, | ||
orderMapping | ||
) | ||
orderMapping, | ||
), | ||
); | ||
@@ -163,3 +163,3 @@ result.info.numberResults++; | ||
possibilities[currentPosition], | ||
possibilities[currentPosition - 1] | ||
possibilities[currentPosition - 1], | ||
); | ||
@@ -180,3 +180,3 @@ } else { | ||
result.mfs.sort((a, b) => a.ms.ppm - b.ms.ppm); | ||
result.mfs.sort((a, b) => Math.abs(a.ms.ppm) - Math.abs(b.ms.ppm)); | ||
return result; | ||
@@ -201,3 +201,3 @@ }; | ||
ionization, | ||
orderMapping | ||
orderMapping, | ||
) { | ||
@@ -211,3 +211,3 @@ let lastPossibility = possibilities[possibilities.length - 1]; | ||
charge: lastPossibility.currentCharge - ionization.charge, | ||
ionization | ||
ionization, | ||
}; | ||
@@ -256,5 +256,5 @@ | ||
currentAtom.maxInnerMass) / | ||
currentAtom.em | ||
currentAtom.em, | ||
), | ||
currentAtom.originalMinCount | ||
currentAtom.originalMinCount, | ||
); | ||
@@ -266,5 +266,5 @@ currentAtom.currentMaxCount = Math.min( | ||
currentAtom.minInnerMass) / | ||
currentAtom.em | ||
currentAtom.em, | ||
), | ||
currentAtom.originalMaxCount | ||
currentAtom.originalMaxCount, | ||
); | ||
@@ -293,3 +293,3 @@ currentAtom.currentCount = currentAtom.currentMinCount - 1; | ||
`max:${a.currentMaxCount}`, | ||
`charge:${a.currentCharge}` | ||
`charge:${a.currentCharge}`, | ||
]); | ||
@@ -296,0 +296,0 @@ } |
@@ -11,25 +11,51 @@ 'use strict'; | ||
// need to convert to ranges | ||
let parsed = parse(ranges.replace(/ /g, '')); | ||
let parsed = parse(ranges.replace(/[\r\n\t ]/g, '')); | ||
let newRanges = []; | ||
let current; | ||
let current = { | ||
mf: '', | ||
min: 1, | ||
max: 1, | ||
}; | ||
// example ClBr2(CH2)0-2NO | ||
// the idea is that has long as we don't have a range we don't really care | ||
// there is a limitation is that the range has to be first level of parenthesis | ||
let parenthesisLevel = 0; | ||
let currentMF = ''; // start at an atom first level or a parenthesis | ||
for (let item of parsed) { | ||
switch (item.kind) { | ||
case Kind.ATOM: | ||
current = { | ||
mf: item.value, | ||
min: 1, | ||
max: 1 | ||
}; | ||
newRanges.push(current); | ||
if (parenthesisLevel === 0 && currentMF) { | ||
current.mf += currentMF; | ||
currentMF = ''; | ||
} | ||
currentMF += item.value; | ||
break; | ||
case Kind.MULTIPLIER: | ||
if (current) { | ||
current.min = item.value; | ||
current.max = item.value; | ||
if (parenthesisLevel === 0 && currentMF) { | ||
current.mf += currentMF + item.value; | ||
currentMF = ''; | ||
} else { | ||
currentMF += item.value; | ||
} | ||
break; | ||
case Kind.MULTIPLIER_RANGE: | ||
current.min = item.value.from; | ||
current.max = item.value.to; | ||
if (parenthesisLevel !== 0) { | ||
throw new Error('Range multiplier can only be at the first level'); | ||
} | ||
newRanges.push({ | ||
mf: currentMF, | ||
min: item.value.from, | ||
max: item.value.to, | ||
}); | ||
currentMF = ''; | ||
break; | ||
case Kind.OPENING_PARENTHESIS: | ||
parenthesisLevel++; | ||
currentMF += '('; | ||
break; | ||
case Kind.CLOSING_PARENTHESIS: | ||
parenthesisLevel--; | ||
currentMF += ')'; | ||
break; | ||
default: | ||
@@ -39,5 +65,12 @@ throw Error(`can not preprocess ${ranges}`); | ||
} | ||
if (currentMF) { | ||
current.mf += currentMF; | ||
} | ||
if (current.mf) { | ||
newRanges.push(current); | ||
} | ||
ranges = newRanges; | ||
} | ||
var possibilities = []; | ||
let possibilities = []; | ||
for (let i = 0; i < ranges.length; i++) { | ||
@@ -66,3 +99,3 @@ let range = ranges[i]; | ||
maxMass: 0, | ||
innerCharge: false | ||
innerCharge: false, | ||
}; | ||
@@ -80,3 +113,3 @@ possibilities.push(possibility); | ||
possibilities = possibilities.filter( | ||
(r) => r.originalMinCount !== 0 || r.originalMaxCount !== 0 | ||
(r) => r.originalMinCount !== 0 || r.originalMaxCount !== 0, | ||
); | ||
@@ -83,0 +116,0 @@ // we will sort the way we analyse the data |
@@ -9,3 +9,7 @@ 'use strict'; | ||
let TargetMassCache = function TargetMassCache(targetMass, possibilities, options = {}) { | ||
let TargetMassCache = function TargetMassCache( | ||
targetMass, | ||
possibilities, | ||
options = {}, | ||
) { | ||
const { | ||
@@ -16,3 +20,3 @@ allowNeutral = false, // msem because em in this case ! | ||
charge = 0, | ||
precision = 100 | ||
precision = 100, | ||
} = options; | ||
@@ -22,4 +26,10 @@ if (!possibilities || possibilities.length === 0) return {}; | ||
let firstPossibility = possibilities[0]; | ||
let currentMinCharge = Math.max(minCharge, firstPossibility.minCharge + charge); | ||
let currentMaxCharge = Math.min(maxCharge, firstPossibility.maxCharge + charge); | ||
let currentMinCharge = Math.max( | ||
minCharge, | ||
firstPossibility.minCharge + charge, | ||
); | ||
let currentMaxCharge = Math.min( | ||
maxCharge, | ||
firstPossibility.maxCharge + charge, | ||
); | ||
@@ -33,3 +43,3 @@ this.minCharge = currentMinCharge; | ||
let maxMass = 0; | ||
let range = targetMass * precision / 1e6; | ||
let range = (targetMass * precision) / 1e6; | ||
for (let i = 0; i < size; i++) { | ||
@@ -46,11 +56,14 @@ let currentCharge = i + this.minCharge; | ||
} else { | ||
minMass = (targetMass - range) * Math.abs(currentCharge) + ELECTRON_MASS * currentCharge; | ||
maxMass = (targetMass + range) * Math.abs(currentCharge) + ELECTRON_MASS * currentCharge; | ||
minMass = | ||
(targetMass - range) * Math.abs(currentCharge) + | ||
ELECTRON_MASS * currentCharge; | ||
maxMass = | ||
(targetMass + range) * Math.abs(currentCharge) + | ||
ELECTRON_MASS * currentCharge; | ||
} | ||
this.data.push({ | ||
charge: currentCharge, | ||
minMass, | ||
maxMass | ||
maxMass, | ||
}); | ||
@@ -63,7 +76,11 @@ } | ||
TargetMassCache.prototype.getMinMass = function (charge) { | ||
return (this.data[charge - this.minCharge]) ? this.data[charge - this.minCharge].minMass : Number.MAX_SAFE_INTEGER; | ||
return this.data[charge - this.minCharge] | ||
? this.data[charge - this.minCharge].minMass | ||
: Number.MAX_SAFE_INTEGER; | ||
}; | ||
TargetMassCache.prototype.getMaxMass = function (charge) { | ||
return (this.data[charge - this.minCharge]) ? this.data[charge - this.minCharge].maxMass : Number.MIN_SAFE_INTEGER; | ||
return this.data[charge - this.minCharge] | ||
? this.data[charge - this.minCharge].maxMass | ||
: Number.MIN_SAFE_INTEGER; | ||
}; |
33775
974
+ Addedatom-sorter@0.12.0(transitive)
+ Addedchemical-elements@0.12.1(transitive)
+ Addedchemical-groups@0.12.1(transitive)
+ Addedmf-parser@0.12.0(transitive)
+ Addedmf-utilities@0.12.1(transitive)
+ Addedpapaparse@5.5.2(transitive)
- Removedatom-sorter@0.9.1(transitive)
- Removedchemical-elements@0.9.1(transitive)
- Removedchemical-groups@0.9.1(transitive)
- Removedmf-parser@0.9.1(transitive)
- Removedmf-utilities@0.9.1(transitive)
- Removedpapaparse@4.6.3(transitive)
Updatedatom-sorter@^0.12.0
Updatedchemical-elements@^0.12.0
Updatedmf-parser@^0.12.0
Updatedmf-utilities@^0.12.0