@datagrok/bio 2.11.30 → 2.11.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/36.js +1 -1
  3. package/dist/36.js.map +1 -1
  4. package/dist/42.js +1 -1
  5. package/dist/42.js.map +1 -1
  6. package/dist/590.js +2 -0
  7. package/dist/590.js.map +1 -0
  8. package/dist/709.js +1 -2
  9. package/dist/709.js.map +1 -1
  10. package/dist/79.js.map +1 -1
  11. package/dist/895.js +3 -0
  12. package/dist/895.js.map +1 -0
  13. package/dist/package-test.js +8 -1
  14. package/dist/package-test.js.LICENSE.txt +1 -0
  15. package/dist/package-test.js.map +1 -1
  16. package/dist/package.js +8 -1
  17. package/dist/package.js.LICENSE.txt +1 -0
  18. package/dist/package.js.map +1 -1
  19. package/files/{data → monomer-libraries}/HELMCoreLibrary.json +594 -594
  20. package/files/tests/libraries/HELMmonomerSchema.json +96 -0
  21. package/package.json +12 -10
  22. package/scripts/sequence_generator.md +48 -0
  23. package/scripts/sequence_generator.py +515 -256
  24. package/src/package-test.ts +4 -0
  25. package/src/package.ts +26 -24
  26. package/src/tests/WebLogo-layout-tests.ts +37 -0
  27. package/src/tests/WebLogo-positions-test.ts +5 -0
  28. package/src/tests/WebLogo-project-tests.ts +63 -0
  29. package/src/tests/activity-cliffs-tests.ts +3 -2
  30. package/src/tests/monomer-libraries-tests.ts +7 -4
  31. package/src/tests/scoring.ts +3 -2
  32. package/src/tests/substructure-filters-tests.ts +3 -2
  33. package/src/tests/to-atomic-level-tests.ts +3 -2
  34. package/src/utils/helm-to-molfile.ts +3 -3
  35. package/src/utils/monomer-lib/lib-manager.ts +116 -0
  36. package/src/utils/monomer-lib/library-file-manager/consts.ts +1 -0
  37. package/src/utils/monomer-lib/library-file-manager/custom-monomer-lib-handlers.ts +80 -0
  38. package/src/utils/monomer-lib/library-file-manager/event-manager.ts +58 -0
  39. package/src/utils/monomer-lib/library-file-manager/file-manager.ts +187 -0
  40. package/src/utils/monomer-lib/library-file-manager/file-validator.ts +56 -0
  41. package/src/utils/monomer-lib/library-file-manager/style.css +8 -0
  42. package/src/utils/monomer-lib/library-file-manager/ui.ts +224 -0
  43. package/src/utils/monomer-lib/monomer-lib.ts +114 -0
  44. package/src/utils/poly-tool/const.ts +28 -0
  45. package/src/utils/poly-tool/monomer-lib-handler.ts +115 -0
  46. package/src/utils/poly-tool/types.ts +6 -0
  47. package/src/utils/poly-tool/ui.ts +2 -2
  48. package/src/viewers/vd-regions-viewer.ts +5 -4
  49. package/src/viewers/web-logo-viewer.ts +6 -5
  50. package/src/widgets/bio-substructure-filter.ts +4 -1
  51. package/files/libraries/HELMCoreLibrary.json +0 -18218
  52. package/src/utils/monomer-lib.ts +0 -305
  53. /package/dist/{709.js.LICENSE.txt → 895.js.LICENSE.txt} +0 -0
@@ -1,305 +0,0 @@
1
- import * as grok from 'datagrok-api/grok';
2
- import * as ui from 'datagrok-api/ui';
3
- import * as DG from 'datagrok-api/dg';
4
-
5
- import {Observable, Subject} from 'rxjs';
6
-
7
- import {IMonomerLib, Monomer} from '@datagrok-libraries/bio/src/types/index';
8
- import {
9
- LibSettings, getUserLibSettings, setUserLibSettings, LIB_PATH
10
- } from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
11
- import {MolfileHandler} from '@datagrok-libraries/chem-meta/src/parsing-utils/molfile-handler';
12
- import {PolyToolMonomerLibHandler} from '@datagrok-libraries/bio/src/utils/poly-tool/monomer-lib-handler';
13
- import {
14
- createJsonMonomerLibFromSdf,
15
- IMonomerLibHelper,
16
- } from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
17
- import {
18
- HELM_REQUIRED_FIELDS as REQ, HELM_OPTIONAL_FIELDS as OPT, HELM_POLYMER_TYPE
19
- } from '@datagrok-libraries/bio/src/utils/const';
20
-
21
- import {_package} from '../package';
22
-
23
-
24
- export async function getLibFileNameList(): Promise<string[]> {
25
- // list files recursively because permissions are available for folders only
26
- const res: string[] = await Promise.all((await grok.dapi.files.list(LIB_PATH, true, ''))
27
- .map(async (it) => {
28
- // Get relative path (to LIB_PATH)
29
- return it.fullPath.substring(LIB_PATH.length);
30
- }));
31
- return res;
32
- }
33
-
34
- export async function manageFiles() {
35
- const a = ui.dialog({title: 'Manage files'})
36
- //@ts-ignore
37
- .add(ui.fileBrowser({path: 'System:AppData/Bio/libraries'}).root)
38
- .addButton('OK', () => a.close())
39
- .show();
40
- }
41
-
42
- export async function getLibraryPanelUI(): Promise<DG.Widget> {
43
- //@ts-ignore
44
- const filesButton: HTMLButtonElement = ui.button('Manage', manageFiles);
45
- const inputsForm: HTMLElement = ui.inputs([]);
46
- const libFileNameList: string[] = await getLibFileNameList();
47
-
48
- const settings = await getUserLibSettings();
49
-
50
- for (const libFileName of libFileNameList) {
51
- const libInput: DG.InputBase<boolean | null> = ui.boolInput(libFileName, !settings.exclude.includes(libFileName),
52
- () => {
53
- if (libInput.value == true) {
54
- // Checked library remove from excluded list
55
- settings.exclude = settings.exclude.filter((l) => l != libFileName);
56
- } else {
57
- // Unchecked library add to excluded list
58
- if (!settings.exclude.includes(libFileName)) settings.exclude.push(libFileName);
59
- }
60
- setUserLibSettings(settings).then(async () => {
61
- await MonomerLibHelper.instance.loadLibraries(true); // from libraryPanel()
62
- grok.shell.info('Monomer library user settings saved.');
63
- });
64
- });
65
- inputsForm.append(libInput.root);
66
- }
67
- return new DG.Widget(ui.divV([inputsForm, ui.div(filesButton)]));
68
- }
69
-
70
- export class MonomerLib implements IMonomerLib {
71
- public readonly error: string | undefined;
72
-
73
- private _monomers: { [polymerType: string]: { [monomerSymbol: string]: Monomer } } = {};
74
- private _onChanged = new Subject<any>();
75
-
76
- constructor(monomers: { [polymerType: string]: { [monomerSymbol: string]: Monomer } }, error?: string) {
77
- this._monomers = monomers;
78
- this.error = error;
79
- }
80
-
81
- getMonomer(polymerType: string, monomerSymbol: string): Monomer | null {
82
- if (polymerType in this._monomers! && monomerSymbol in this._monomers![polymerType])
83
- return this._monomers![polymerType][monomerSymbol];
84
- else
85
- return null;
86
- }
87
-
88
- getPolymerTypes(): string[] {
89
- return Object.keys(this._monomers);
90
- }
91
-
92
- getMonomerMolsByPolymerType(polymerType: string): { [monomerSymbol: string]: string } {
93
- const res: { [monomerSymbol: string]: string } = {};
94
-
95
- Object.keys(this._monomers[polymerType] ?? {}).forEach((monomerSymbol) => {
96
- res[monomerSymbol] = this._monomers[polymerType][monomerSymbol].molfile;
97
- });
98
-
99
- return res;
100
- }
101
-
102
- getMonomerSymbolsByType(polymerType: string): string[] {
103
- return Object.keys(this._monomers[polymerType]);
104
- }
105
-
106
- /** Get a list of monomers with specified element attached to specified
107
- * R-group
108
- * WARNING: RGroup numbering starts from 1, not 0*/
109
- getMonomerSymbolsByRGroup(rGroupNumber: number, polymerType: string, element?: string): string[] {
110
- const monomerSymbols = this.getMonomerSymbolsByType(polymerType);
111
- let monomers = monomerSymbols.map((sym) => this.getMonomer(polymerType, sym));
112
- monomers = monomers.filter((el) => el !== null);
113
- if (monomers.length === 0)
114
- return [];
115
-
116
- function findAllIndices<T>(arr: T[], element: T): number[] {
117
- return arr.map((value, index) => (value === element ? index : -1))
118
- .filter((index) => index !== -1);
119
- }
120
-
121
- monomers = monomers.filter((monomer) => {
122
- if (!monomer?.rgroups)
123
- return false;
124
- let criterion = monomer?.rgroups.length >= rGroupNumber;
125
- const molfileHandler = MolfileHandler.getInstance(monomer.molfile);
126
- const rGroupIndices = findAllIndices(molfileHandler.atomTypes, 'R#');
127
- criterion &&= true;
128
- return criterion;
129
- });
130
- return monomers.map((monomer) => monomer?.symbol!);
131
- }
132
-
133
- get onChanged(): Observable<any> {
134
- return this._onChanged;
135
- }
136
-
137
- private _updateInt(lib: IMonomerLib): void {
138
- const typesNew = lib.getPolymerTypes();
139
- const types = this.getPolymerTypes();
140
-
141
- typesNew.forEach((type) => {
142
- //could possibly rewrite -> TODO: check duplicated monomer symbol
143
-
144
- if (!types.includes(type))
145
- this._monomers![type] = {};
146
-
147
- const monomers = lib.getMonomerSymbolsByType(type);
148
- monomers.forEach((monomerSymbol) => {
149
- this._monomers[type][monomerSymbol] = lib.getMonomer(type, monomerSymbol)!;
150
- });
151
- });
152
- }
153
-
154
- public update(lib: IMonomerLib): void {
155
- this._updateInt(lib);
156
- this._onChanged.next();
157
- }
158
-
159
- public updateLibs(libList: IMonomerLib[], reload: boolean = false): void {
160
- if (reload) this._monomers = {};
161
- for (const lib of libList) if (!lib.error) this._updateInt(lib);
162
- this._onChanged.next();
163
- }
164
-
165
- public clear(): void {
166
- this._monomers = {};
167
- this._onChanged.next();
168
- }
169
- }
170
-
171
- type MonomerLibWindowType = Window & { $monomerLibHelper: MonomerLibHelper };
172
- declare const window: MonomerLibWindowType;
173
-
174
- export class MonomerLibHelper implements IMonomerLibHelper {
175
- private readonly _monomerLib: MonomerLib = new MonomerLib({});
176
-
177
- /** Protect constructor to prevent multiple instantiation. */
178
- protected constructor() {}
179
-
180
- /** Singleton monomer library
181
- * @return {MonomerLibHelper} MonomerLibHelper instance
182
- */
183
- getBioLib(): IMonomerLib {
184
- return this._monomerLib;
185
- }
186
-
187
- /** Allows syncing with managing settings/loading libraries */
188
- public loadLibrariesPromise: Promise<void> = Promise.resolve();
189
-
190
- /** Loads libraries based on settings in user storage {@link LIB_STORAGE_NAME}
191
- * @param {boolean} reload Clean {@link monomerLib} before load libraries [false]
192
- */
193
- async loadLibraries(reload: boolean = false): Promise<void> {
194
- return this.loadLibrariesPromise = this.loadLibrariesPromise.then(async () => {
195
- // This function is not allowed to throw any exception,
196
- // because it will prevent further handling monomer library settings
197
- // through blocking this.loadLibrariesPromise
198
- try {
199
- const [libFileNameList, settings]: [string[], LibSettings] = await Promise.all([
200
- getLibFileNameList(),
201
- getUserLibSettings(),
202
- ]);
203
- const filteredLibFnList = libFileNameList
204
- .filter((libFileName) => !settings.exclude.includes(libFileName))
205
- .filter((libFileName) => settings.explicit.length > 0 ? settings.explicit.includes(libFileName) : true);
206
- const libs: IMonomerLib[] = await Promise.all(filteredLibFnList
207
- .map((libFileName) => {
208
- //TODO handle whether files are in place
209
- return this.readLibrary(LIB_PATH, libFileName).catch((err: any) => {
210
- const errMsg: string = `Loading monomers from '${libFileName}' error: ` +
211
- `${err instanceof Error ? err.message : err.toString()}`;
212
- return new MonomerLib({}, errMsg);
213
- });
214
- }));
215
- this._monomerLib.updateLibs(libs, reload);
216
- } catch (err: any) {
217
- const errMsg: string = 'Loading monomer libraries error: ' +
218
- `${err instanceof Error ? err.message : err.toString()}`;
219
- grok.shell.warning(errMsg);
220
-
221
- const errStack = err instanceof Error ? err.stack : undefined;
222
- _package.logger.error(errMsg, undefined, errStack);
223
- }
224
- });
225
- }
226
-
227
- /** Reads library from file shares, handles .json and .sdf
228
- * @param {string} path Path to library file
229
- * @param {string} fileName Name of library file
230
- * @return {Promise<IMonomerLib>} Promise of IMonomerLib
231
- */
232
- async readLibrary(path: string, fileName: string): Promise<IMonomerLib> {
233
- let rawLibData: any[] = [];
234
- let file;
235
- let dfSdf;
236
- const fileSource = new DG.FileSource(path);
237
- if (fileName.endsWith('.sdf')) {
238
- const funcList: DG.Func[] = DG.Func.find({package: 'Chem', name: 'importSdf'});
239
- if (funcList.length === 1) {
240
- file = await fileSource.readAsBytes(fileName);
241
- dfSdf = await grok.functions.call('Chem:importSdf', {bytes: file});
242
- rawLibData = createJsonMonomerLibFromSdf(dfSdf[0]);
243
- } else {
244
- grok.shell.warning('Chem package is not installed');
245
- }
246
- } else if (fileName.endsWith('.json')) {
247
- const file = await fileSource.readAsText(fileName);
248
- rawLibData = JSON.parse(file);
249
- } else if (fileName.endsWith('.csv')) {
250
- // todo: replace by DataFrame's method after update of js-api
251
- function toJson(df: DG.DataFrame): any[] {
252
- return Array.from({length: df.rowCount}, (_, idx) =>
253
- df.columns.names().reduce((entry: { [key: string]: any }, colName) => {
254
- entry[colName] = df.get(colName, idx);
255
- return entry;
256
- }, {})
257
- );
258
- }
259
-
260
- const df = await fileSource.readCsv(fileName);
261
- const json = toJson(df);
262
- const polyToolMonomerLib = new PolyToolMonomerLibHandler(json);
263
- if (polyToolMonomerLib.isValid())
264
- rawLibData = polyToolMonomerLib.getJsonMonomerLib();
265
- else
266
- throw new Error('Invalid format of CSV monomer lib');
267
- } else {
268
- throw new Error('Monomer library of unknown file format, supported formats: SDF, JSON, CSV');
269
- }
270
-
271
- const monomers: { [polymerType: string]: { [monomerSymbol: string]: Monomer } } = {};
272
- const polymerTypes: string[] = [];
273
- rawLibData.forEach((monomer) => {
274
- if (!polymerTypes.includes(monomer[REQ.POLYMER_TYPE])) {
275
- monomers[monomer[REQ.POLYMER_TYPE]] = {};
276
- polymerTypes.push(monomer[REQ.POLYMER_TYPE]);
277
- }
278
- monomers[monomer[REQ.POLYMER_TYPE]][monomer[REQ.SYMBOL]] = monomer as Monomer;
279
- });
280
-
281
- return new MonomerLib(monomers);
282
- }
283
-
284
- /** Reset user settings to the specified library. WARNING: clears user * settings */
285
- public async selectSpecifiedLibraries(libFileNameList: string[]): Promise<void> {
286
- const invalidNames = await this.getInvalidFileNames(libFileNameList);
287
- if (invalidNames.length > 0)
288
- throw new Error(`Cannot select libraries ${invalidNames}: no such library in the list`);
289
- const settings = await getUserLibSettings();
290
- settings.exclude = (await getLibFileNameList()).filter((fileName) => !libFileNameList.includes(fileName));
291
- await setUserLibSettings(settings);
292
- }
293
-
294
- private async getInvalidFileNames(libFileNameList: string[]): Promise<string[]> {
295
- const availableFileNames = await getLibFileNameList();
296
- const invalidNames = libFileNameList.filter((fileName) => !availableFileNames.includes(fileName));
297
- return invalidNames;
298
- }
299
-
300
- // -- Instance singleton --
301
- public static get instance(): MonomerLibHelper {
302
- if (!window.$monomerLibHelper) window.$monomerLibHelper = new MonomerLibHelper();
303
- return window.$monomerLibHelper;
304
- }
305
- }
File without changes