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; |
{ | ||
"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
1325461
49
3415
+ Addedmass-fragmentation@0.3.0(transitive)
- Removedmass-fragmentation@0.2.5(transitive)
Updatedisotopic-distribution@^2.2.0
Updatedmass-fragmentation@^0.3.0
Updatedmf-finder@^2.4.0
Updatedmf-from-google-sheet@^2.0.7
Updatedmf-generator@^2.1.1
Updatedmf-parser@^2.3.0
Updatedmf-utilities@^2.0.4
Updatedms-spectrum@^2.4.0
Updatednucleotide@^2.1.0