New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

emdb

Package Overview
Dependencies
Maintainers
2
Versions
134
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

emdb - npm Package Compare versions

Comparing version 2.3.0 to 2.4.0

229

lib/index.js

@@ -20,3 +20,2 @@ 'use strict';

var peaksSimilarity = require('peaks-similarity');
var chemicalElements = require('chemical-elements');
var Regression = require('ml-regression-theil-sen');

@@ -1024,224 +1023,3 @@ var mlSpectraProcessing = require('ml-spectra-processing');

async function fetchJSON(url) {
const result = await crossFetch__default["default"](url);
return result.json();
}
/**
* Generates a database 'pubchem' based on all molecular formula available
* in the database and a monoisotopic mass.
* @param {number|string|number[]} masses - Observed monoisotopic mass
* @param {object} [options={}]
* @param {string} [options.databaseName='pubchem']
* @param {string} [options.ionizations=''] - string containing a comma separated list of modifications
* @param {number} [options.precision=1000] - Precision of the monoisotopic mass in ppm
* @param {string} [options.ranges=''] -
* @param {number} [options.limit=1000] - Maximal number of entries to return
* @param {number} [options.minPubchemEntries=5] - Minimal number of molecules having a specific MF
* @param {string} [options.url='https://pubchem.cheminfo.org/mfs/v1/fromEM'] - URL of the webservice
*/
async function searchPubchem(masses, options = {}) {
const {
url = 'https://pubchem.cheminfo.org/mfs/v1/fromEM',
precision = 1000,
limit = 1000,
ranges = '',
minPubchemEntries = 5,
} = options;
if (typeof masses === 'number') {
masses = [masses];
}
if (typeof masses === 'string') {
masses = masses.split(/[\r\n\t,; ]+/).map(Number);
}
let allowedEMs;
if (ranges) {
const allowedEMsArray = [];
for (let mass of masses) {
(
await mfFinder.findMFs(mass, {
ionizations: options.ionizations,
precision,
ranges,
limit: 100000,
})
).mfs.forEach((mf) => allowedEMsArray.push(mf.em));
}
allowedEMs = Float64Array.from(allowedEMsArray).sort();
}
let promises = [];
let ionizations = mfUtilities.preprocessIonizations(options.ionizations);
for (let mass of masses) {
for (let ionization of ionizations) {
let realMass =
mass * Math.abs(ionization.charge || 1) -
ionization.em +
chemicalElements.ELECTRON_MASS * ionization.charge;
const pubchemURL = `${url}?em=${realMass}&precision=${precision}&limit=${limit}&minPubchemEntries=${minPubchemEntries}`;
promises.push(fetchJSON(pubchemURL));
}
}
let results = await Promise.all(promises);
let mfs = [];
for (let i = 0; i < results.length; i++) {
for (const entry of results[i].data) {
if (
allowedEMs &&
!allowedEMs.find((em) => Math.abs(em - entry.em) < 0.0000001)
) {
continue;
}
try {
let mfInfo = new mfParser.MF(entry._id).getInfo();
mfInfo.ionization = ionizations[i];
mfInfo.em = mfInfo.monoisotopicMass;
mfInfo.ms = mfUtilities.getMsInfo(mfInfo, {
targetMass: masses,
}).ms;
mfInfo.info = { nbPubchemEntries: entry.count };
mfs.push(mfInfo);
} catch (e) {
// eslint-disable-next-line no-console
console.warn(`${e}`);
}
}
}
// because we can combine many ionizations we should resort the data
mfs.sort((a, b) => Math.abs(a.ms.ppm) - Math.abs(b.ms.ppm));
return mfs;
}
/**
* Generates a database 'pubchem' based on all molecular formula available
* in the database and a monoisotopic mass.
* @param {number|string|number[]} masses - Observed monoisotopic mass
* @param {object} [options={}]
* @param {string} [options.databaseName='pubchem']
* @param {string} [options.ionizations=''] - string containing a comma separated list of modifications
* @param {string} [options.ranges=''] -
* @param {number} [options.precision=1000] - Precision of the monoisotopic mass in ppm
* @param {number} [options.limit=1000] - Maximal number of entries to return
* @param {string} [options.url='https://pubchem.cheminfo.org/activesOrNaturals/v1/fromEM'] - URL of the webservice
*/
async function searchActivesOrNaturals(masses, options = {}) {
const {
url = 'https://pubchem.cheminfo.org/activesOrNaturals/v1/fromEM',
precision = 1000,
limit = 1000,
ranges = '',
} = options;
if (typeof masses === 'number') {
masses = [masses];
}
if (typeof masses === 'string') {
masses = masses.split(/[\r\n\t,; ]+/).map(Number);
}
let promises = [];
let ionizations = mfUtilities.preprocessIonizations(options.ionizations);
let allowedEMs; // we prefer to use the exact mass rather than MF
if (ranges) {
const allowedEMsArray = [];
for (let mass of masses) {
(
await mfFinder.findMFs(mass, {
ionizations: options.ionizations,
precision,
ranges,
limit: 100000,
})
).mfs.forEach((mf) => allowedEMsArray.push(mf.em));
}
allowedEMs = Float64Array.from(allowedEMsArray).sort();
}
for (let mass of masses) {
for (let ionization of ionizations) {
let realMass =
mass * Math.abs(ionization.charge || 1) -
ionization.em +
chemicalElements.ELECTRON_MASS * ionization.charge;
const pubchemURL = `${url}?em=${realMass}&precision=${precision}&limit=${limit}`;
promises.push(fetchJSON(pubchemURL));
}
}
let results = await Promise.all(promises);
let mfs = [];
for (let i = 0; i < results.length; i++) {
for (let mf of results[i].data) {
try {
// would it be more efficient to filter later ???
if (
allowedEMs &&
!allowedEMs.find((em) => Math.abs(em - mf.data.em) < 0.0000001)
) {
continue;
}
let mfInfo = new mfParser.MF(mf.data.mf).getInfo();
mfInfo.ionization = ionizations[i];
mfInfo.em = mfInfo.monoisotopicMass;
mfInfo.ms = mfUtilities.getMsInfo(mfInfo, {
targetMass: masses,
}).ms;
const info = mf.data;
info.idCode = mf.id;
delete info.em;
delete info.charge;
delete info.unsaturation;
delete info.mf;
mfInfo.info = mf.data;
mfs.push(mfInfo);
} catch (e) {
// eslint-disable-next-line no-console
console.warn(`${e}`);
}
}
}
// we will now group the data per mf
const grouped = {};
for (const mf of mfs) {
if (!grouped[mf.mf]) {
grouped[mf.mf] = {
mf: mf.mf,
em: mf.em,
ms: mf.ms,
molecules: [],
nbNatural: 0,
nbBioactive: 0,
nbPubmed: 0,
nbWithMassSpectra: 0,
};
}
grouped[mf.mf].molecules.push(mf);
if (mf.info.naturalProduct) grouped[mf.mf].nbNatural++;
if (mf.info.bioActive) grouped[mf.mf].nbBioactive++;
if (mf.info.nbMassSpectra) grouped[mf.mf].nbWithMassSpectra++;
if (mf.info.pubmeds && mf.info.pubmeds.length > 0) {
grouped[mf.mf].nbPubmed++;
}
}
const groupedArray = Object.keys(grouped).map((key) => grouped[key]);
// because we can combine many ionizations we should resort the data
groupedArray.sort((a, b) => Math.abs(a.ms.ppm) - Math.abs(b.ms.ppm));
return groupedArray;
}
/**
* Calculates a function that allows post-calibration on mass spectra based on the error in assignment

@@ -1327,2 +1105,7 @@ * @param {*} similarities

async function fetchJSON(url) {
const result = await crossFetch__default["default"](url);
return result.json();
}
/**

@@ -1507,3 +1290,1 @@ * A class that deals with database of monoisotopic mass and molecular formula

exports.massShifts = massShifts;
exports.searchActivesOrNaturals = searchActivesOrNaturals;
exports.searchPubchem = searchPubchem;

22

package.json
{
"name": "emdb",
"version": "2.3.0",
"version": "2.4.0",
"description": "Database manager for exact mass query",

@@ -26,15 +26,15 @@ "main": "lib/index.js",

"cross-fetch": "^3.1.5",
"isotopic-distribution": "^2.1.0",
"isotopic-distribution": "^2.2.0",
"jszip": "^3.10.1",
"mass-fragmentation": "^0.2.5",
"mf-finder": "^2.3.0",
"mf-from-google-sheet": "^2.0.6",
"mf-generator": "^2.1.0",
"mass-fragmentation": "^0.3.0",
"mf-finder": "^2.4.0",
"mf-from-google-sheet": "^2.0.7",
"mf-generator": "^2.1.1",
"mf-matcher": "^2.1.0",
"mf-parser": "^2.2.1",
"mf-utilities": "^2.0.3",
"mf-parser": "^2.3.0",
"mf-utilities": "^2.0.4",
"ml-regression-theil-sen": "^2.0.0",
"ml-spectra-processing": "^12.0.0",
"ms-spectrum": "^2.3.2",
"nucleotide": "^2.0.3",
"ms-spectrum": "^2.4.0",
"nucleotide": "^2.1.0",
"openchemlib-utils": "^2.4.0",

@@ -49,3 +49,3 @@ "peaks-similarity": "^3.1.1",

},
"gitHead": "d309de1c7a86730c8e4f0bd836896e1a16c95cb7"
"gitHead": "2f92cd4423018e7dad9594565f1fae4557de0ca3"
}
import { loadKnapSack } from '../loadKnapSack';
jest.setTimeout(30000);
test('loadKnapSack', async () => {

@@ -5,0 +4,0 @@ let data = await loadKnapSack();

import { EMDB } from '..';
jest.setTimeout(30000);
describe('test search', () => {

@@ -6,0 +4,0 @@ it('should filter one database', async () => {

import { EMDB } from '..';
jest.setTimeout(30000);
describe('test search commercial', () => {

@@ -6,0 +4,0 @@ it('should filter the commercial database', async () => {

import { EMDB } from '..';
jest.setTimeout(20000);
describe('test searchMSEM', () => {

@@ -6,0 +4,0 @@ it('should filter one database with existing ionization', async () => {

@@ -17,4 +17,2 @@ import { Spectrum } from 'ms-spectrum';

export * from './searchPubchem.js';
export * from './searchActivesOrNaturals.js';
export * from './massShifts.js';

@@ -21,0 +19,0 @@ export * from './util/fetchJSON.js';

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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