Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mf-generator

Package Overview
Dependencies
Maintainers
1
Versions
94
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mf-generator - npm Package Compare versions

Comparing version 0.9.1 to 0.12.0

src/__tests__/__snapshots__/generateMFs.test.js.snap

15

package.json
{
"name": "mf-generator",
"version": "0.9.1",
"version": "0.12.0",
"description": "",

@@ -21,9 +21,10 @@ "main": "src/index.js",

"dependencies": {
"chemical-elements": "^0.9.1",
"mf-finder": "^0.9.1",
"mf-matcher": "^0.9.1",
"mf-parser": "^0.9.1",
"mf-utilities": "^0.9.1",
"chemical-elements": "^0.12.0",
"mf-finder": "^0.12.0",
"mf-matcher": "^0.12.0",
"mf-parser": "^0.12.0",
"mf-utilities": "^0.12.0",
"sum-object-keys": "^1.0.2"
}
},
"gitHead": "aa2e6571c5f7121dda616b7d6920b7a653a8f9c7"
}

@@ -6,4 +6,4 @@ 'use strict';

test('generateMFs from array of array with comment', function () {
var mfsArray = [['C', 'H$YY'], [], [''], ['Cl', 'Br$XX']];
var result = generateMFs(mfsArray);
let mfsArray = [['C', 'H$YY'], [], [''], ['Cl', 'Br$XX']];
let result = generateMFs(mfsArray);
expect(result[0].mf).toBe('HCl');

@@ -15,4 +15,4 @@ expect(result[0].comment).toBe('YY');

test('generateMFs from array of string with empty', function () {
var mfsArray = ['C,H,', 'Cl,Br'];
var result = generateMFs(mfsArray).map((entry) => entry.mf);
let mfsArray = ['C,H,', 'Cl,Br'];
let result = generateMFs(mfsArray).map((entry) => entry.mf);
expect(result).toStrictEqual(['Cl', 'HCl', 'CCl', 'Br', 'HBr', 'CBr']);

@@ -22,5 +22,5 @@ });

test('generateMFs from array of string with comment', function () {
var mfsArray = ['C.H.O', '+,++', ['Cl', 'Br$XX']];
var result = generateMFs(mfsArray).sort((a, b) => a.em - b.em);
expect(result[0].mf).toBe('HCl(+1)');
let mfsArray = ['C.H.O', '+,++', ['Cl', 'Br$XX']];
let result = generateMFs(mfsArray).sort((a, b) => a.ms.em - b.ms.em);
expect(result[0].mf).toBe('HCl(+2)');
expect(result).toHaveLength(12);

@@ -30,4 +30,4 @@ });

test('generateMFs from array of string with some range and non range', function () {
var mfsArray = ['CN0-2'];
var result = generateMFs(mfsArray);
let mfsArray = ['CN0-2'];
let result = generateMFs(mfsArray);
expect(result[0].mf).toBe('C');

@@ -40,4 +40,4 @@ expect(result[1].mf).toBe('CN');

test('From array of string with some range and non range CN0-2O00-1K', function () {
var mfsArray = ['CN0-2O00-1K'];
var result = generateMFs(mfsArray);
let mfsArray = ['CN0-2O00-1K'];
let result = generateMFs(mfsArray);
expect(result[0].mf).toBe('CK');

@@ -53,4 +53,4 @@ expect(result[1].mf).toBe('CKN');

test('From array of string with some range and non range NaK0-2', function () {
var mfsArray = ['NaK0-2'];
var result = generateMFs(mfsArray);
let mfsArray = ['NaK0-2'];
let result = generateMFs(mfsArray);
expect(result[0].mf).toBe('Na');

@@ -63,4 +63,4 @@ expect(result[1].mf).toBe('KNa');

test('From array of string with some range and non range C(Me(N2))0-2(CH3)0-1K', function () {
var mfsArray = ['C(Me(N2))0-2(CH3)0-1K'];
var result = generateMFs(mfsArray, { canonizeMF: false, uniqueMFs: false });
let mfsArray = ['C(Me(N2))0-2(CH3)0-1K'];
let result = generateMFs(mfsArray, { canonizeMF: false, uniqueMFs: false });
expect(result[0].mf).toBe('CK');

@@ -76,4 +76,4 @@ expect(result[1].mf).toBe('C(CH3)K');

test('From array of string with some range', function () {
var mfsArray = ['C1-3N0-2Cl0-0BrO1-1.C2-3H3-4', ['C', 'O']];
var result = generateMFs(mfsArray, { canonizeMF: true });
let mfsArray = ['C1-3N0-2Cl0-0BrO1-1.C2-3H3-4', ['C', 'O']];
let result = generateMFs(mfsArray, { canonizeMF: true });
expect(result[0].mf).toBe('C3H3');

@@ -84,5 +84,5 @@ expect(result).toHaveLength(26);

test('From array of string chem em and msem', function () {
var mfsArray = ['C0-2.O', ['+', '(-)', '++', '(--)']];
let mfsArray = ['C0-2.O', ['+', '(-)', '++', '(--)']];
var result = generateMFs(mfsArray);
let result = generateMFs(mfsArray);
expect(result[0].mf).toMatch(/^(.*)$/);

@@ -94,4 +94,4 @@ expect(result[0].charge).not.toBe(0);

test('From array of string to large array', function () {
var mfsArray = ['C0-100', 'O0-100'];
var result = generateMFs(mfsArray);
let mfsArray = ['C0-100', 'O0-100'];
let result = generateMFs(mfsArray);
expect(result).toHaveLength(101 * 101);

@@ -101,4 +101,4 @@ });

test('From array of string to large array and filter', function () {
var mfsArray = ['C0-100', 'O0-100'];
var result = generateMFs(mfsArray, { filter: { minEM: 0.1, maxEM: 13 } });
let mfsArray = ['C0-100', 'O0-100'];
let result = generateMFs(mfsArray, { filter: { minEM: 0.1, maxEM: 13 } });
expect(result).toHaveLength(1);

@@ -108,5 +108,5 @@ });

test('From array of string to large array and filter unsaturation', function () {
var mfsArray = ['C0-100', 'H0-100'];
var result = generateMFs(mfsArray, {
filter: { unsaturation: { min: 0, max: 1 } }
let mfsArray = ['C0-100', 'H0-100'];
let result = generateMFs(mfsArray, {
filter: { unsaturation: { min: 0, max: 1 } },
});

@@ -117,5 +117,5 @@ expect(result).toHaveLength(151);

test('From array of string to large array and filter unsaturation min/max and integer unsaturation', function () {
var mfsArray = ['C0-100', 'H0-100'];
var result = generateMFs(mfsArray, {
filter: { unsaturation: { min: 0, max: 1, onlyInteger: true } }
let mfsArray = ['C0-100', 'H0-100'];
let result = generateMFs(mfsArray, {
filter: { unsaturation: { min: 0, max: 1, onlyInteger: true } },
});

@@ -126,3 +126,3 @@ expect(result).toHaveLength(101);

test('Combine with ionizations', function () {
var result = generateMFs(['C1-2'], { ionizations: 'H+,Na+,H++' });
let result = generateMFs(['C1-2'], { ionizations: 'H+,Na+,H++' });
expect(result.map((a) => a.ms.em).sort((a, b) => a - b)).toStrictEqual([

@@ -134,3 +134,3 @@ 6.50336393620593,

34.989220702090925,
46.989220702090925
46.989220702090925,
]);

@@ -140,4 +140,4 @@ });

test('Strange comments', function () {
var mfsArray = ['C$1>10', 'O$D2>20'];
var result = generateMFs(mfsArray);
let mfsArray = ['C$1>10', 'O$D2>20'];
let result = generateMFs(mfsArray);
expect(result[0].mf).toBe('CO');

@@ -148,20 +148,12 @@ expect(result[0].comment).toBe('1>10 D2>20');

test('Check info', function () {
var mfsArray = ['C', '', 'C5(C)2'];
var result = generateMFs(mfsArray, { canonizeMF: true })[0];
expect(result).toStrictEqual({
mf: 'C8',
em: 96,
ms: { em: 0, charge: 0, ionization: '' },
mw: 96.08588717388199,
charge: 0,
ionization: { mf: '', charge: 0, em: 0 },
parts: ['C', undefined, 'C5(C)2'],
atoms: { C: 8 },
unsaturation: 9
});
let mfsArray = ['C', '', 'C5(C)2'];
let result = generateMFs(mfsArray, { canonizeMF: true })[0];
expect(JSON.stringify(result)).toBe(
'{"charge":0,"em":96,"mw":96.08588717388199,"ionization":{"mf":"","em":0,"charge":0},"unsaturation":9,"atoms":{"C":8},"ms":{"ionization":"","em":0,"charge":0},"parts":["C",null,"C5(C)2"],"mf":"C8"}',
);
});
test('generateMFs from array of array with negative ionisation', function () {
var mfsArray = ['H2', ['Cl', 'Br']];
var result = generateMFs(mfsArray, { ionizations: '(H+)-2' });
let mfsArray = ['H2', ['Cl', 'Br']];
let result = generateMFs(mfsArray, { ionizations: '(H+)-2' });
expect(result[0].ms.em).toBe(17.484974920909067);

@@ -173,4 +165,4 @@ expect(result[1].ms.em).toBe(39.45971737990907);

test('generateMFs from array with charge and range', function () {
var mfsArray = ['(H+)2-3'];
var result = generateMFs(mfsArray, { ionizations: '(H+)-2,Na+' });
let mfsArray = ['(H+)2-3'];
let result = generateMFs(mfsArray, { ionizations: '(H+)-2,Na+' });
expect(result.map((a) => a.ms.em).sort((a, b) => a - b)).toStrictEqual([

@@ -180,4 +172,29 @@ 0,

6.50276251476343,
8.334591202244264
8.334591202244264,
]);
});
test('generateMFs from array with target masses', function () {
let mfsArray = ['C1-100'];
let result = generateMFs(mfsArray, {
ionizations: '+,++',
filter: {
targetMasses: [120, 240],
precision: 10,
targetIntensities: [1, 5],
},
});
expect(result).toHaveLength(4);
expect(result.sort((a, b) => a.em - b.em)).toMatchSnapshot();
});
test('generateMFs from array with charge and negative range', function () {
let mfsArray = ['(H+)-2--4'];
let result = generateMFs(mfsArray);
expect(result.map((a) => a.ms.em).sort((a, b) => a - b)).toStrictEqual([
-1.0072764523209299,
-1.0072764523209299,
-1.0072764523209299,
]);
});

@@ -7,3 +7,3 @@ 'use strict';

const preprocessIonizations = require('mf-utilities/src/preprocessIonizations');
const processRange = require('mf-utilities/src/processRange');
/**

@@ -15,20 +15,22 @@ * Generate all the possible combinations of molecular formula and calculate

* @param keys
* @param {object} options
* @param {number} [options.limit=10000000] - Maximum number of results
* @param {boolean} [canonizeMF=true] - Canonize molecular formula
* @param {boolean} [uniqueMFs=true] - Force canonization and make MF unique
* @param {string} [ionizations=''] - Comma separated list of ionizations (to charge the molecule)
* @param {number} [options.filter.minMass=0] - Minimal monoisotopic mass
* @param {number} [options.filter.maxMass=+Infinity] - Maximal monoisotopic mass
* @param {number} [options.filter.minEM=0] - Minimal neutral monoisotopic mass
* @param {number} [options.filter.maxEM=+Infinity] - Maximal neutral monoisotopic mass
* @param {number} [options.filter.targetMass] - Experimental observed mass
* @param {number} [options.filter.precision=1000] - Precision
* @param {number} [options.filter.minCharge=-Infinity] - Minimal charge
* @param {number} [options.filter.maxCharge=+Infinity] - Maximal charge
* @param {number} [options.filter.minUnsaturation=-Infinity] - Minimal unsaturation
* @param {number} [options.filter.maxUnsaturation=+Infinity] - Maximal unsaturation
* @param {number} [options.filter.onlyIntegerUnsaturation=false] - Integer unsaturation
* @param {number} [options.filter.onlyNonIntegerUnsaturation=false] - Non integer unsaturation
* @param {object} [options.filter.atoms] - object of atom:{min, max}
* @param {object} [options={}]
* @param {number} [options.limit=10000000] - Maximum number of results
* @param {boolean} [canonizeMF=true] - Canonize molecular formula
* @param {boolean} [uniqueMFs=true] - Force canonization and make MF unique
* @param {string} [ionizations=''] - Comma separated list of ionizations (to charge the molecule)
* @param {number} [options.filter.minMass=0] - Minimal monoisotopic mass
* @param {number} [options.filter.maxMass=+Infinity] - Maximal monoisotopic mass
* @param {number} [options.filter.minEM=0] - Minimal neutral monoisotopic mass
* @param {number} [options.filter.maxEM=+Infinity] - Maximal neutral monoisotopic mass
* @param {number} [options.filter.precision=1000] - The precision on the experimental mass
* @param {number} [options.filter.targetMass] - Target mass, allows to calculate error and filter results
* @param {Array<number>} [options.filter.targetMasses] - Target masses: SORTED array of numbers
* @param {number} [options.filter.precision=1000] - Precision
* @param {number} [options.filter.minCharge=-Infinity] - Minimal charge
* @param {number} [options.filter.maxCharge=+Infinity] - Maximal charge
* @param {number} [options.filter.minUnsaturation=-Infinity] - Minimal unsaturation
* @param {number} [options.filter.maxUnsaturation=+Infinity] - Maximal unsaturation
* @param {number} [options.filter.onlyIntegerUnsaturation=false] - Integer unsaturation
* @param {number} [options.filter.onlyNonIntegerUnsaturation=false] - Non integer unsaturation
* @param {object} [options.filter.atoms] - object of atom:{min, max}
* @returns {Array}

@@ -48,6 +50,6 @@ */

// we allow String delimited by ". , or ;" instead of an array
// we allow String delimited by ". or ;" instead of an array
for (let i = 0; i < keys.length; i++) {
if (!Array.isArray(keys[i])) {
keys[i] = keys[i].split(/[.,;]/);
keys[i] = keys[i].split(/[.,]/);
}

@@ -57,3 +59,3 @@ }

// we allow ranges in a string ...
// problem with ranges is that we need to now to what the range applies
// problem with ranges is that we need to know to what the range applies
for (let i = 0; i < keys.length; i++) {

@@ -66,3 +68,4 @@ let parts = keys[i];

part = part.replace(/\$.*/, '').replace(/\s/g, '');
if (~part.indexOf('-')) {
if (part.match(/[0-9]-[0-9-]/)) {
// deal with negative numbers
// there are ranges ... we are in trouble !

@@ -86,3 +89,2 @@ newParts = newParts.concat(processRange(part, comment));

let evolution = 0;
while (position < currents.length) {

@@ -102,3 +104,3 @@ if (currents[position] < sizes[position]) {

throw new Error(
`You have reached the limit of ${limit}. You could still change this value using the limit option but it is likely to crash.`
`You have reached the limit of ${limit}. You could still change this value using the limit option but it is likely to crash.`,
);

@@ -108,5 +110,4 @@ }

appendResult(results, currents, keys, options);
if (uniqueMFs) {
var uniqueMFsObject = {};
let uniqueMFsObject = {};
results.forEach((r) => {

@@ -121,3 +122,3 @@ uniqueMFsObject[r.mf + r.ionization.mf] = r;

var ems = {};
let ems = {};

@@ -135,3 +136,3 @@ // internal method used as a cache

unsaturation: (info.unsaturation - 1) * 2,
atoms: info.atoms
atoms: info.atoms,
};

@@ -143,8 +144,8 @@ }

function getEMFromParts(parts, currents, ionization) {
var charge = 0;
var em = 0;
var mw = 0;
var unsaturation = 0;
var validUnsaturation = true;
var atoms = {};
let charge = 0;
let em = 0;
let mw = 0;
let unsaturation = 0;
let validUnsaturation = true;
let atoms = {};

@@ -171,3 +172,3 @@ for (let i = 0; i < parts.length; i++) {

unsaturation: validUnsaturation ? unsaturation / 2 + 1 : undefined,
atoms
atoms,
};

@@ -178,3 +179,2 @@ }

const { canonizeMF, filter, ionizations } = options;
// this script is designed to combine molecular formula

@@ -188,4 +188,3 @@ // that may contain comments after a "$" sign

let match = matcher(result, filter);
if (!match) return;
if (!match) continue;
result.ms = match.ms;

@@ -208,3 +207,2 @@ result.ionization = match.ionization;

}
if (canonizeMF) {

@@ -219,98 +217,1 @@ result.mf = new MF(result.mf).toMF();

}
function processRange(string, comment) {
var results = [];
var parts = string.split(/([0-9]+-[0-9]+)/).filter((v) => v); // remove empty parts
let position = -1;
var mfs = [];
for (let i = 0; i < parts.length; i++) {
let part = parts[i];
if (!~part.search(/[0-9]-[0-9]/)) {
position++;
mfs[position] = {
mf: part,
min: 1,
max: 1
};
} else {
mfs[position].min = part.replace(/^(-?[0-9]*)-(-?[0-9]*)/, '$1') >> 0;
mfs[position].max = part.replace(/^(-?[0-9]*)-(-?[0-9]*)/, '$2') >> 0;
}
}
let currents = new Array(mfs.length);
for (let i = 0; i < currents.length; i++) {
currents[i] = mfs[i].min;
}
position = 0;
while (position < currents.length) {
if (currents[position] < mfs[position].max) {
results.push(getMF(mfs, currents, comment));
currents[position]++;
for (let i = 0; i < position; i++) {
currents[i] = mfs[i].min;
}
position = 0;
} else {
position++;
}
}
results.push(getMF(mfs, currents, comment));
return results;
}
function getMF(mfs, currents, comment) {
let mf = '';
for (let i = 0; i < mfs.length; i++) {
if (currents[i] === 0) {
// TODO we need to remove from currents[i] till we reach another part of the MF
mf += removeMFLastPart(mfs[i].mf);
} else {
mf += mfs[i].mf;
if (currents[i] !== 1) {
mf += currents[i];
}
}
}
if (comment) mf += `$${comment}`;
return mf;
}
/*
Allows to remove the last part of a MF. Useful when you have something with '0' times.
C10H -> C10
C10((Me)N) -> C10
C10Ala -> C10
C10Ala((Me)N) -> C10Ala
*/
function removeMFLastPart(mf) {
let parenthesis = 0;
let start = true;
for (let i = mf.length - 1; i >= 0; i--) {
let ascii = mf.charCodeAt(i);
if (ascii > 96 && ascii < 123) {
// lowercase
if (!start && !parenthesis) {
return mf.substr(0, i + 1);
}
} else if (ascii > 64 && ascii < 91) {
// uppercase
if (!start && !parenthesis) {
return mf.substr(0, i + 1);
}
start = false;
} else if (ascii === 40) {
// (
parenthesis--;
if (!parenthesis) return mf.substr(0, i);
} else if (ascii === 41) {
// )
parenthesis++;
} else {
start = false;
if (!parenthesis) return mf.substr(0, i + 1);
}
}
return '';
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc