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

nmr-predictor

Package Overview
Dependencies
Maintainers
6
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nmr-predictor - npm Package Compare versions

Comparing version 0.5.3 to 1.0.0

src/group.js

29

package.json
{
"name": "nmr-predictor",
"version": "0.5.3",
"version": "1.0.0",
"description": "NMR chemical shift predictor",

@@ -18,17 +18,12 @@ "keywords": [],

"scripts": {
"test": "npm run test-mocha",
"test-mocha": "mocha --compilers js:babel-register --require should --reporter mocha-better-spec-reporter --recursive src/**/__tests__/**/*.js",
"build": "cheminfo build --no-uglify"
"eslint": "eslint src test --cache",
"eslint-fix": "npm run eslint -- --fix",
"test": "npm run test-mocha && npm run eslint",
"test-mocha": "mocha --require should --reporter mocha-better-spec-reporter --recursive",
"build": "cheminfo build"
},
"devDependencies": {
"babel-cli": "^6.2.0",
"babel-core": "^6.2.1",
"babel-plugin-transform-es2015-block-scoping": "^6.1.18",
"babel-preset-es2015-node4": "^2.0.1",
"babel-register": "^6.2.0",
"babelify": "^7.2.0",
"babili": "0.0.8",
"cheminfo-tools": "^1.13.0",
"cheminfo-tools": "^1.15.0",
"eslint": "^3.9.1",
"eslint-config-cheminfo": "^1.5.2",
"eslint-config-cheminfo": "^1.7.0",
"eslint-plugin-no-only-tests": "^1.1.0",

@@ -40,9 +35,7 @@ "mocha": "^3.1.2",

"dependencies": {
"openchemlib-extended": "1.9.1",
"ml-matrix": "^1.1.2",
"ml-matrix": "^2.3.0",
"new-array": "^1.0.0",
"isomorphic-fetch": "2.2.1",
"es6-promise": "4.0.5",
"form-data": "2.1.2"
"openchemlib-extended-minimal": "^2.0.0",
"superagent": "^3.5.0"
}
}

@@ -18,8 +18,6 @@ # nmr-predictor

``` js
```js
'use strict';
const NmrPredictor = require('..');
const request = require('request');
const fs = require('fs');
const predictor = require('..');

@@ -49,8 +47,24 @@ const molfile = `Benzene, ethyl-, ID: C100414

// 1D proton prediction
predictor.fetchProton().then(function () {
console.log(predictor.proton(molfile));
});
var predictor = new NmrPredictor("spinus");
predictor.predict(molfile).then(prediction => {
console.log(prediction);
// 2D HSQC prediction
Promise.all([
predictor.fetchProton(),
predictor.fetchCarbon()
]).then(function (dbs) {
return predictor.twod(predictor.proton(molfile), predictor.carbon(molfile), molfile);
});
// 2D HSQC with spinus
Promise.all([
predictor.spinus(molfile),
predictor.fetchCarbon()
]).then(function (results) {
return predictor.twod(results[0], predictor.carbon(molfile), molfile);
});
```
## License

@@ -60,4 +74,4 @@

[npm-image]: https://img.shields.io/npm/v/cheminfo-nmr-predictor.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/cheminfo-nmr-predictor
[npm-image]: https://img.shields.io/npm/v/nmr-predictor.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/nmr-predictor
[travis-image]: https://img.shields.io/travis/cheminfo-js/nmr-predictor/master.svg?style=flat-square

@@ -67,3 +81,3 @@ [travis-url]: https://travis-ci.org/cheminfo-js/nmr-predictor

[david-url]: https://david-dm.org/cheminfo-js/nmr-predictor
[download-image]: https://img.shields.io/npm/dm/cheminfo-nmr-predictor.svg?style=flat-square
[download-url]: https://www.npmjs.com/package/cheminfo-nmr-predictor
[download-image]: https://img.shields.io/npm/dm/nmr-predictor.svg?style=flat-square
[download-url]: https://www.npmjs.com/package/nmr-predictor

@@ -1,419 +0,81 @@

'use strict'
/**
* Created by acastillo on 7/5/16.
*/
const OCLE = require('openchemlib-extended');
const Matrix = require('ml-matrix');
const newArray = require('new-array');
require('es6-promise').polyfill();
require('isomorphic-fetch');
const FormData = require('form-data');
'use strict';
const defaultOptions = {atomLabel:'H', ignoreLabile: true, use: 'median'};
const superagent = require('superagent');
class NmrPredictor {
const normalizeOptions = require('./normalizeOptions');
const queryByHose = require('./queryByHose');
const spinus = require('./spinus');
const twoD = require('./twoD');
constructor(db) {
this.db = db;
}
const defaultProtonUrl = 'https://raw.githubusercontent.com/cheminfo-js/nmr-predictor/master/data/h1.json';
const defaultCarbonUrl = 'https://raw.githubusercontent.com/cheminfo-js/nmr-predictor/master/data/nmrshiftdb2.json';
setDB(db) {
this.db = db;
}
const databases = {};
spinus(molfile, options) {
var mol = molfile;
if(typeof molfile === 'string') {
mol = OCLE.Molecule.fromMolfile(molfile);
mol.addImplicitHydrogens();
}
let opt = Object.assign({}, defaultOptions, options);
return fromSpinus(mol, opt).then(prediction => {return group(prediction, opt)});
}
protonSync(molfile, options) {
if(!this.db) {
this.db = {"H": fetchDB("H")};
}
var mol = molfile;
if(typeof molfile === 'string') {
mol = OCLE.Molecule.fromMolfile(molfile);
mol.addImplicitHydrogens();
}
let opt = Object.assign({}, defaultOptions, options, {atomLabel: "H"});
return group(queryByHose(mol, this.db, opt), opt);
}
proton(molfile, options) {
if(!this.db)
this.db = {};
if(!this.db['H']) {
return fetch('https://raw.githubusercontent.com/cheminfo-js/nmr-predictor/master/data/h1.json', {timeout: 5000})
.then(value => {return value.text()}).then(body => {
this.db['H'] = JSON.parse(body);
return this.protonSync(molfile, options);
});
} else {
let result = this.protonSync(molfile, options);
return new Promise(function(resolve, reject){
resolve(result);
});
}
}
carbonSync(molfile, options) {
var mol = molfile;
if(typeof molfile === 'string') {
mol = OCLE.Molecule.fromMolfile(molfile);
mol.addImplicitHydrogens();
}
let opt = Object.assign({}, defaultOptions, options, {atomLabel: "C"});
return group(queryByHose(mol, this.db, opt), opt);
}
carbon(molfile, options) {
if(!this.db)
this.db = {};
if(!this.db['C']) {
return fetch('https://raw.githubusercontent.com/cheminfo-js/nmr-predictor/master/data/nmrshiftdb2.json',
{timeout: 20000})
.then(value => {return value.text()}).then(body => {
this.db['C'] = JSON.parse(body);
return this.carbonSync(molfile, options);
});
} else {
let result = this.carbonSync(molfile, options);
return new Promise(function(resolve, reject){
resolve(result);
});
}
}
twoD(dim1, dim2, molfile, opt) {
var result = this.towDSync(dim1, dim2, molfile, opt);
return new Promise(function(resolve, reject) {
resolve(result);
});
}
towDSync(dim1, dim2, molfile, opt) {
let mol = molfile;
let fromAtomLabel = '';
let toAtomLabel = '';
if(dim1 && dim1.length > 0) {
fromAtomLabel = dim1[0].atomLabel;
}
if(dim2 && dim2.length > 0) {
toAtomLabel = dim2[0].atomLabel;
}
let options = Object.assign({}, {minLength: 1, maxLength:3}, opt,
{fromLabel: fromAtomLabel, toLabel: toAtomLabel});
if(typeof molfile === 'string') {
mol = OCLE.Molecule.fromMolfile(molfile);
mol.addImplicitHydrogens();
}
let paths = mol.getAllPaths(options);
let idMap1 = {};
dim1.forEach(prediction => {
idMap1[prediction["diaIDs"][0]] = prediction;
});
let idMap2 = {};
dim2.forEach(prediction => {
idMap2[prediction["diaIDs"][0]] = prediction;
});
paths.forEach(element => {
element.fromChemicalShift = idMap1[element.fromDiaID].delta;
element.toChemicalShift = idMap2[element.toDiaID].delta;
element.fromAtomLabel = fromAtomLabel;
element.toAtomLabel = toAtomLabel;
//@TODO Add the coupling constants in any case!!!!!!
element.j = getCouplingConstant(idMap1, element.fromDiaID, element.toDiaID);
});
return paths;
}
function fetchProton(url = defaultProtonUrl, dbName = 'proton') {
return fetch(url, dbName, 'proton');
}
function group(prediction, param) {
if(param && param.group) {
prediction.sort(function(a, b) {
if(a.diaIDs[0] < b.diaIDs[0]) return -1;
if(a.diaIDs[0] > b.diaIDs[0]) return 1;
return 0;
});
for(var i = prediction.length - 2; i >= 0; i--){
if(prediction[i].diaIDs[0] === prediction[i + 1].diaIDs[0]){
prediction[i].integral += prediction[i + 1].integral;
prediction[i].atomIDs = prediction[i].atomIDs.concat(prediction[i + 1].atomIDs);
prediction.splice(i + 1, 1);
}
}
}
return prediction;
function fetchCarbon(url = defaultCarbonUrl, dbName = 'carbon') {
return fetch(url, dbName, 'carbon');
}
function getCouplingConstant(idMap, fromDiaID, toDiaID) {
let j = idMap[fromDiaID].j;
if(j) {
let index = j.length - 1;
while(index-- > 0) {
if(j[index].diaID === toDiaID) {
return j[index].coupling;
}
function fetch(url, dbName, type) {
if (databases[dbName] && databases[dbName].type === type && databases[dbName].url === url) {
if (databases[dbName].fetching) {
return databases[dbName].fetching;
}
return Promise.resolve(databases[dbName].db);
}
return 0;
}
/**
* This function towD shift for 1H-NMR, from a molfile by using the cheminfo reference data base.
* @param molfile: string A molfile content
* @returns +Object an array of NMRSignal1D
*/
function queryByHose(mol, db, options) {
var currentDB = null;
const atomLabel = options.atomLabel || 'H';
const use = options.use;
if (db) {
currentDB = db[atomLabel];
}
else {
currentDB = [[], [], [], [], [], [], []];
}
options.debug = options.debug || false;
var algorithm = options.algorithm || 0;
var levels = options.hoseLevels || [6, 5, 4, 3, 2];
var couplings = options.getCouplings || false;
levels.sort(function(a, b) {
return b - a;
const database = {
type,
url,
db: null,
fetching: null
};
databases[dbName] = database;
const fetching = superagent.get(url).then((res) => {
const db = res.body ? res.body : JSON.parse(res.text);
database.db = db;
database.fetching = false;
return db;
}).catch((e) => {
delete databases[dbName];
throw e;
});
var diaIDs = mol.getGroupedDiastereotopicAtomIDs({atomLabel: atomLabel});
var infoCOSY = [];//mol.getCouplings();
if(couplings) {
// infoCOSY = mol.predictCouplings();
}
var atoms = {};
var atomNumbers = [];
var i, k, j, atom, hosesString;
for (j = diaIDs.length - 1; j >= 0; j--) {
hosesString = OCLE.Util.getHoseCodesFromDiastereotopicID(diaIDs[j].oclID, {maxSphereSize: levels[0], type: algorithm});
atom = {
diaIDs: [diaIDs[j].oclID + '']
};
for(k = 0; k < levels.length; k++) {
atom['hose'+levels[k]] = hosesString[levels[k]-1]+'';
}
for (k = diaIDs[j].atoms.length - 1; k >= 0; k--) {
atoms[diaIDs[j].atoms[k]] = JSON.parse(JSON.stringify(atom));
atomNumbers.push(diaIDs[j].atoms[k]);
}
}
//Now, we towD the chimical shift by using our copy of NMRShiftDB
//var script2 = 'select chemicalShift FROM assignment where ';//hose5='dgH`EBYReZYiIjjjjj@OzP`NET'';
var toReturn = new Array(atomNumbers.length);
for (j = 0; j < atomNumbers.length; j++) {
atom = atoms[atomNumbers[j]];
var res = null;
k = 0;
//A really simple query
while(res === null && k < levels.length) {
if(currentDB[levels[k]]) {
res = currentDB[levels[k]][atom['hose' + levels[k]]];
}
k++;
}
if (res == null) {
res = { cs: null, ncs: 0, std: 0, min: 0, max: 0 };//Default values
}
atom.atomLabel = atomLabel;
atom.level = levels[k-1];
atom.delta = res.cs;
if(use === 'median' && res.median)
atom.delta = res.median;
else if (use === 'mean' && res.mean)
atom.delta = res.mean;
atom.integral = 1;
atom.atomIDs = ['' + atomNumbers[j]];
atom.ncs = res.ncs;
atom.std = res.std;
atom.min = res.min;
atom.max = res.max;
atom.j = [];
//Add the predicted couplings
//console.log(atomNumbers[j]+' '+infoCOSY[0].atom1);
for (i = infoCOSY.length - 1; i >= 0; i--) {
if (infoCOSY[i].atom1 - 1 == atomNumbers[j] && infoCOSY[i].coupling > 2) {
atom.j.push({
'assignment': infoCOSY[i].atom2 - 1 + '',//Put the diaID instead
'diaID': infoCOSY[i].diaID2,
'coupling': infoCOSY[i].coupling,
'multiplicity': 'd'
});
}
}
toReturn[j] = atom;
}
//TODO this will not work because getPaths is not implemented yet!!!!
if(options.ignoreLabile) {
var linksOH = mol.getAllPaths({
fromLabel: 'H',
toLabel: 'O',
minLength: 1,
maxLength: 1
});
var linksNH = mol.getAllPaths({
fromLabel: 'H',
toLabel: 'N',
minLength: 1,
maxLength: 1
});
for(j = toReturn.length-1; j >= 0; j--) {
for(var k = 0; k < linksOH.length; k++) {
if(toReturn[j].diaIDs[0] === linksOH[k].fromDiaID) {
toReturn.splice(j, 1);
break;
}
}
}
//console.log(h1pred.length);
for(j = toReturn.length-1; j >= 0; j--) {
for(var k = 0;k < linksNH.length; k++) {
if(toReturn[j].diaIDs[0] === linksNH[k].fromDiaID) {
toReturn.splice(j, 1);
break;
}
}
}
}
return toReturn;
database.fetching = fetching;
return fetching;
}
function fromSpinus(mol, options){
let form = new FormData();
form.append('molfile', mol.toMolfile());
return fetch('https://www.nmrdb.org/service/predictor', {
method: 'POST',
body: form
}).then(value => {return value.text()}).then(body => {
//Convert to the ranges format and include the diaID for each atomID
const data = spinusParser(body);
const ids = data.ids;
const jc = data.couplingConstants;
const cs = data.chemicalShifts;
const multiplicity = data.multiplicity;
const integrals = data.integrals;
const nspins = cs.length;
const diaIDs = mol.getGroupedDiastereotopicAtomIDs({atomLabel: 'H'});
var result = new Array(nspins);
var atoms = {};
var atomNumbers = [];
var i, j, k, oclID, tmpCS;
var csByOclID = {};
for (j = diaIDs.length - 1; j >= 0; j--) {
oclID = diaIDs[j].oclID + '';
for (k = diaIDs[j].atoms.length - 1; k >= 0; k--) {
atoms[diaIDs[j].atoms[k]] = oclID;
atomNumbers.push(diaIDs[j].atoms[k]);
if(!csByOclID[oclID]){
csByOclID[oclID] = {nc: 1, cs: cs[ids[diaIDs[j].atoms[k]]]};
} else {
csByOclID[oclID].nc++;
csByOclID[oclID].cs += cs[ids[diaIDs[j].atoms[k]]];
}
}
}
//Average the entries for the equivalent protons
var idsKeys = Object.keys(ids);
for (i = 0; i < nspins; i++) {
tmpCS = csByOclID[atoms[idsKeys[i]]].cs / csByOclID[atoms[idsKeys[i]]].nc;
result[i] = {atomIDs: [idsKeys[i]], diaIDs: [atoms[idsKeys[i]]], integral: integrals[i],
delta: tmpCS, atomLabel: 'H', j: []};
for (j = 0; j < nspins; j++) {
if(jc[i][j] !== 0 ) {
result[i].j.push({
'assignment': idsKeys[j],
'diaID': atoms[idsKeys[j]],
'coupling': jc[i][j],
'multiplicity': multiplicityToString(multiplicity[j])
});
}
}
}
return result;
}).catch(ex => {return new Error('http request fail ' + ex)});
function proton(molecule, options) {
[molecule, options] = normalizeOptions(molecule, options);
const db = getDb(options.db || 'proton', 'proton');
options.atomLabel = 'H';
return queryByHose(molecule, db, options);
}
function multiplicityToString(mul) {
switch(mul) {
case 2:
return 'd';
break;
case 3:
return 't';
break;
case 4:
return 'q';
break;
default:
return '';
}
function carbon(molecule, options) {
[molecule, options] = normalizeOptions(molecule, options);
const db = getDb(options.db || 'carbon', 'carbon');
options.atomLabel = 'C';
return queryByHose(molecule, db, options);
}
function spinusParser(result){
var lines = result.split('\n');
var nspins = lines.length - 1;
var cs = new Array(nspins);
var integrals = new Array(nspins);
var ids = {};
var jc = Matrix.zeros(nspins, nspins);
var i, j;
for (i = 0; i < nspins; i++) {
var tokens = lines[i].split('\t');
cs[i] = +tokens[2];
ids[tokens[0] - 1] = i;
integrals[i] = 1;//+tokens[5];//Is it always 1??
}
for (i = 0; i < nspins; i++) {
tokens = lines[i].split('\t');
var nCoup = (tokens.length - 4) / 3;
for (j = 0; j < nCoup; j++) {
var withID = tokens[4 + 3 * j] - 1;
var idx = ids[withID];
jc[i][idx] = (+tokens[6 + 3 * j]);
}
}
for (j = 0; j < nspins; j++) {
for (i = j; i < nspins; i++) {
jc[j][i] = jc[i][j];
}
}
return {ids, chemicalShifts: cs, integrals, couplingConstants: jc, multiplicity: newArray(nspins, 2)};
function getDb(option, type) {
if (typeof option === 'object') return option;
if (typeof option !== 'string') throw new TypeError('database option must be a string or array');
const db = databases[option];
if (!db) throw new Error(`database ${option} does not exist. Did you forget to fetch it?`);
if (db.fetching) throw new Error(`database ${option} is not fetched yet`);
if (db.type !== type) throw new Error(`database ${option} is of type ${db.type} instead of ${type}`);
return db.db;
}
module.exports = NmrPredictor;
module.exports = {
fetchProton,
fetchCarbon,
proton,
carbon,
spinus,
twoD
};
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