-
Notifications
You must be signed in to change notification settings - Fork 2
/
MoleculesDB.js
177 lines (165 loc) · 6.88 KB
/
MoleculesDB.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import appendCSV from './utils/appendCSV';
import appendColor from './utils/appendColor';
import appendEntries from './utils/appendEntries.js';
import appendSDF from './utils/appendSDF';
import appendSmilesList from './utils/appendSmilesList';
import pushEntry from './utils/pushEntry';
import pushMoleculeInfo from './utils/pushMoleculeInfo';
import { search, searchAsync } from './utils/search';
/*
this.db is an object with properties 'oclID' that has as value
an object that contains the following properties:
* molecule: an OCL molecule instance
* index: OCL index used for substructure searching
* properties: all the calculates properties
* data: array containing free data associated with this molecule
*/
export class MoleculesDB {
/**
*
* @param {import('openchemlib')} OCL - openchemlib library
* @param {object} [options={}]
* @param {boolean} [options.computeProperties=false]
*/
constructor(OCL, options = {}) {
const { computeProperties = false } = options;
this.OCL = OCL;
this.db = {};
this.statistics = null;
this.computeProperties = computeProperties;
this.searcher = new OCL.SSSearcherWithIndex();
}
/**
* Append an array of entries to the current database. An entry is an object that by default should contain a 'ocl' property containing idCode and optionally index and coordinates
* @param {*} moleculesDB
* @param {object[]} entries
* @param {object} [options={}]
* @param {string} [options.idCodePath='ocl.idCode']
* @param {string} [options.indexPath='ocl.index']
* @param {string} [options.coordinatesPath='ocl.coordinates']
* @param {string} [options.mwPath='mw']
* @param {string} [options.smilesPath]
* @param {string} [options.molfilePath]
* @param {function} [options.onStep] call back to execute after each molecule
*/
appendEntries(entries, options) {
return appendEntries(this, entries, {
computeProperties: this.computeProperties,
...options,
});
}
/**
* append to the current database a CSV file
* @param {string|ArrayBuffer} csv - text file containing the comma separated value file
* @param {object} [options={}]
* @param {boolean} [options.header=true]
* @param {boolean} [options.dynamicTyping=true]
* @param {boolean} [options.skipEmptyLines=true]
* @param {function} [options.onStep] call back to execute after each molecule
*/
appendCSV(csv, options) {
return appendCSV(this, csv, {
computeProperties: this.computeProperties,
...options,
});
}
/**
* Append a SDF to the current database
* @param {string|ArrayBuffer} sdf - text file containing the sdf
* @param {object} [options={}]
* @param {function} [options.onStep] call back to execute after each molecule
* @returns {DB}
*/
appendSDF(sdf, options) {
return appendSDF(this, sdf, {
computeProperties: this.computeProperties,
...options,
});
}
/**
* Append a SDF to the current database
* @param {string|ArrayBuffer} smiles - text file containing a list of smiles
* @param {object} [options={}]
* @param {function} [options.onStep] call back to execute after each molecule
* @returns {DB}
*/
appendSmilesList(text, options) {
return appendSmilesList(this, text, {
computeProperties: this.computeProperties,
...options,
});
}
/**
* Add a molecule to the current database
* @param {import('openchemlib').Molecule} molecule
* @param {object} [data={}]
* @param {object} [moleculeInfo={}] may contain precalculated index and mw
*/
pushEntry(molecule, data, moleculeInfo) {
pushEntry(this, molecule, data, moleculeInfo);
}
/**
* Add an entry in the database
* @param {object} moleculeInfo - a molecule as a JSON that may contain the following properties: molfile, smiles, idCode, mf, index
* @param {object} [data={}]
*/
pushMoleculeInfo(moleculeInfo, data) {
return pushMoleculeInfo(this, moleculeInfo, data);
}
/**
* Search in a MoleculesDB
* Inside the database all the same molecules are group together
* @param {string|OCL.Molecule} [query] smiles, molfile, idlCode or instance of Molecule to look for
* @param {object} [options={}]
* @param {'smiles'|'idCode'|'smarts'|'molfile'} [options.format='idCode'] - query format
* @param {string} [options.mode='substructure'] - search by 'substructure', 'exact' or 'similarity'
* @param {boolean} [options.flattenResult=true] - The database group the data for the same product. This allows to flatten the result
* @param {boolean} [options.keepMolecule=false] - keep the OCL.Molecule object in the result
* @param {number} [options.limit=Number.MAX_SAFE_INTEGER] - maximal number of result
* @return {Array} array of object of the type {(molecule), idCode, data, properties}
*/
search(query, options) {
return search(this, query, options);
}
/**
* Search in a MoleculesDB
* Inside the database all the same molecules are group together
* @param {string|OCL.Molecule} [query] smiles, molfile, idCode or instance of Molecule to look for
* @param {object} [options={}]
* @param {'smiles'|'idCode'|'smarts'|'molfile'} [options.format='idCode'] - query format
* @param {string} [options.mode='substructure'] - search by 'substructure', 'exact' or 'similarity'
* @param {boolean} [options.flattenResult=true] - The database group the data for the same product. This allows to flatten the result
* @param {boolean} [options.keepMolecule=false] - keep the OCL.Molecule object in the result
* @param {number} [options.limit=Number.MAX_SAFE_INTEGER] - maximal number of result
* @param {number} [options.interval=100] - interval in ms to call the onStep callback
* @param {function} [options.onStep] - callback to execute after each interval
* @param {AbortController} [options.controler] - callback to execute to check if the search should be aborted
* @return {Promise<Array>} array of object of the type {(molecule), idCode, data, properties}
*/
searchAsync(query, options) {
return searchAsync(this, query, options);
}
/**
* Returns an array with the current database
* @returns
*/
getDB() {
return Object.keys(this.db).map((key) => this.db[key]);
}
/**
* Append the property `data.color` to each entry based on a data or property label
* {object} [options={}]
* {string} [options.dataLabel] name of the property from `data` to use
* {string} [options.propertyLabel] name of the property from `properties` to use
* {number} [options.colorLabel='color'] name of the property to add in data that will contain the color
* {number} [options.minValue]
* {number} [options.maxValue]
* {number} [options.minHue=0]
* {number} [options.maxHue=360]
* {number} [options.saturation=65] percent of color saturation
* {number} [options.lightness=65] percent of color lightness
*/
appendColor(options) {
appendColor(this, options);
}
}