@datagrok/bio 2.12.11 → 2.12.13
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.
- package/.eslintrc.json +4 -1
- package/CHANGELOG.md +10 -0
- package/dist/246.js +2 -0
- package/dist/246.js.map +1 -0
- package/dist/42.js +1 -1
- package/dist/42.js.map +1 -1
- package/dist/545.js +3 -0
- package/dist/545.js.map +1 -0
- package/dist/590.js.map +1 -1
- package/dist/package-test.js +5 -5
- package/dist/package-test.js.LICENSE.txt +0 -8
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +5 -5
- package/dist/package.js.LICENSE.txt +0 -8
- package/dist/package.js.map +1 -1
- package/package.json +7 -6
- package/src/package.ts +2 -2
- package/src/tests/renderers-test.ts +47 -1
- package/src/utils/cell-renderer.ts +28 -3
- package/src/utils/helm-to-molfile/converter/connection-list.ts +40 -0
- package/src/utils/helm-to-molfile/converter/const.ts +4 -0
- package/src/utils/helm-to-molfile/converter/converter.ts +124 -0
- package/src/utils/helm-to-molfile/converter/helm.ts +112 -0
- package/src/utils/helm-to-molfile/converter/index.ts +1 -0
- package/src/utils/helm-to-molfile/converter/mol-atoms-v2k.ts +24 -0
- package/src/utils/helm-to-molfile/converter/mol-atoms-v3k.ts +38 -0
- package/src/utils/helm-to-molfile/converter/mol-atoms.ts +44 -0
- package/src/utils/helm-to-molfile/converter/mol-bonds-v2k.ts +26 -0
- package/src/utils/helm-to-molfile/converter/mol-bonds-v3k.ts +30 -0
- package/src/utils/helm-to-molfile/converter/mol-bonds.ts +56 -0
- package/src/utils/helm-to-molfile/converter/mol-wrapper-factory.ts +16 -0
- package/src/utils/helm-to-molfile/converter/mol-wrapper-old.ts +100 -0
- package/src/utils/helm-to-molfile/converter/mol-wrapper-v2k.ts +21 -0
- package/src/utils/helm-to-molfile/converter/mol-wrapper-v3k.ts +21 -0
- package/src/utils/helm-to-molfile/converter/mol-wrapper.ts +79 -0
- package/src/utils/helm-to-molfile/converter/monomer-wrapper.ts +103 -0
- package/src/utils/helm-to-molfile/converter/polymer.ts +99 -0
- package/src/utils/helm-to-molfile/converter/position-handler.ts +23 -0
- package/src/utils/helm-to-molfile/converter/r-group-handler.ts +122 -0
- package/src/utils/helm-to-molfile/converter/simple-polymer.ts +89 -0
- package/src/utils/helm-to-molfile/converter/types.ts +12 -0
- package/src/utils/helm-to-molfile/utils.ts +32 -0
- package/src/utils/poly-tool/const.ts +0 -4
- package/src/utils/poly-tool/transformation.ts +126 -62
- package/src/utils/sequence-to-mol.ts +1 -1
- package/webpack.config.js +4 -3
- package/dist/709.js +0 -2
- package/dist/709.js.map +0 -1
- package/dist/777.js +0 -3
- package/dist/777.js.map +0 -1
- package/link-bio +0 -7
- package/setup +0 -52
- package/src/utils/atomic-works.ts +0 -367
- package/src/utils/helm-to-molfile.ts +0 -959
- /package/dist/{777.js.LICENSE.txt → 545.js.LICENSE.txt} +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import {HELM_MONOMER_TYPE, HELM_POLYMER_TYPE} from '@datagrok-libraries/bio/src/utils/const';
|
|
2
|
+
import {Bond} from './types';
|
|
3
|
+
|
|
4
|
+
/** Wrapper over simple polymer substring of HELM, like RNA1{d(A)p} */
|
|
5
|
+
export class SimplePolymer {
|
|
6
|
+
constructor(private simplePolymer: string) {
|
|
7
|
+
this.polymerType = this.getPolymerType();
|
|
8
|
+
this.idx = this.getIdx();
|
|
9
|
+
const {monomers, monomerTypes} = this.getMonomerSymbolsAndTypes();
|
|
10
|
+
this.monomers = monomers;
|
|
11
|
+
this.monomerTypes = monomerTypes;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
readonly polymerType: string;
|
|
15
|
+
readonly monomers: string[];
|
|
16
|
+
private idx: number;
|
|
17
|
+
private monomerTypes: HELM_MONOMER_TYPE[];
|
|
18
|
+
|
|
19
|
+
/** Simple polymer id in the form 'polymer type' + 'index' */
|
|
20
|
+
get id(): string {
|
|
21
|
+
return this.polymerType + this.idx.toString();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
private getPolymerType(): string {
|
|
25
|
+
const regex = new RegExp(
|
|
26
|
+
`(${HELM_POLYMER_TYPE.PEPTIDE}|${HELM_POLYMER_TYPE.RNA})[0-9]+{`
|
|
27
|
+
);
|
|
28
|
+
const match = this.simplePolymer.match(regex);
|
|
29
|
+
if (!match)
|
|
30
|
+
throw new Error(`Unsupported polymer type in ${this.simplePolymer}`);
|
|
31
|
+
const polymerType = match[1];
|
|
32
|
+
return polymerType;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private getIdx(): number {
|
|
36
|
+
const regex = new RegExp(`${this.polymerType}([0-9]+){`);
|
|
37
|
+
const match = this.simplePolymer.match(regex);
|
|
38
|
+
if (!match)
|
|
39
|
+
throw new Error(`Cannot parse simple polymer id from ${this.simplePolymer}`);
|
|
40
|
+
const id = parseInt(match[1]);
|
|
41
|
+
return id;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private getMonomerSymbolsAndTypes(): {monomers: string[], monomerTypes: HELM_MONOMER_TYPE[]} {
|
|
45
|
+
const helmWrapperRegex = new RegExp(`${this.polymerType}${this.idx}{|}`, 'g');
|
|
46
|
+
const monomerGroups = this.simplePolymer.replace(helmWrapperRegex, '').split('.');
|
|
47
|
+
const monomerList: string[] = [];
|
|
48
|
+
const monomerTypeList: HELM_MONOMER_TYPE[] = [];
|
|
49
|
+
monomerGroups.forEach((monomerGroup) => {
|
|
50
|
+
const splitted = monomerGroup.split(/\(|\)/)
|
|
51
|
+
.map((el) => el.replace(/[\[\]]/g, ''));
|
|
52
|
+
monomerList.push(...splitted);
|
|
53
|
+
// WARNING: only the groups of the form r(A)p, as in RNA, are supported
|
|
54
|
+
const monomerTypes = splitted.map(
|
|
55
|
+
(_, idx) => (idx % 2 === 0) ? HELM_MONOMER_TYPE.BACKBONE : HELM_MONOMER_TYPE.BRANCH
|
|
56
|
+
);
|
|
57
|
+
monomerTypeList.push(...monomerTypes);
|
|
58
|
+
});
|
|
59
|
+
return {monomers: monomerList, monomerTypes: monomerTypeList};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Get list of pairs for bonded monomers, monomers indexed locally
|
|
63
|
+
* (within the simple polymer) */
|
|
64
|
+
getBondData(): Bond[][] {
|
|
65
|
+
const result: Bond[][] = [];
|
|
66
|
+
const backboneMonomerIndices = this.monomerTypes.map((type, idx) => {
|
|
67
|
+
if (type === HELM_MONOMER_TYPE.BACKBONE)
|
|
68
|
+
return idx;
|
|
69
|
+
}
|
|
70
|
+
).filter((idx) => idx !== undefined) as number[];
|
|
71
|
+
const branchMonomerIndices = this.monomerTypes.map((type, idx) => {
|
|
72
|
+
if (type === HELM_MONOMER_TYPE.BRANCH)
|
|
73
|
+
return idx;
|
|
74
|
+
}
|
|
75
|
+
).filter((idx) => idx !== undefined) as number[];
|
|
76
|
+
for (let i = 0; i < backboneMonomerIndices.length - 1; i++) {
|
|
77
|
+
const backboneIdx = backboneMonomerIndices[i];
|
|
78
|
+
const nextBackboneIdx = backboneMonomerIndices[i + 1];
|
|
79
|
+
result.push([{monomerIdx: backboneIdx, rGroupId: 2}, {monomerIdx: nextBackboneIdx, rGroupId: 1}]);
|
|
80
|
+
}
|
|
81
|
+
for (let i = 0; i < branchMonomerIndices.length; i++) {
|
|
82
|
+
const branchIdx = branchMonomerIndices[i];
|
|
83
|
+
const backboneIdx = branchIdx - 1;
|
|
84
|
+
result.push([{monomerIdx: backboneIdx, rGroupId: 3}, {monomerIdx: branchIdx, rGroupId: 1}]);
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type Bond = {
|
|
2
|
+
/** Global (for complex polymer) or local (for simple polymer) monomer index, starting from 0 */
|
|
3
|
+
monomerIdx: number,
|
|
4
|
+
/** RGroup id, starting from 1 */
|
|
5
|
+
rGroupId: number
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** Position of a node in the connection list / bond block */
|
|
9
|
+
export type PositionInBonds = {
|
|
10
|
+
bondLineIdx: number,
|
|
11
|
+
nodeIdx: number,
|
|
12
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/* Do not change these import lines to match external modules in webpack configuration */
|
|
2
|
+
import * as DG from 'datagrok-api/dg';
|
|
3
|
+
import * as grok from 'datagrok-api/grok';
|
|
4
|
+
|
|
5
|
+
import {HelmToMolfileConverter} from './converter';
|
|
6
|
+
|
|
7
|
+
/** Translate HELM column into molfile column and append to the dataframe */
|
|
8
|
+
export async function helm2mol(df: DG.DataFrame, helmCol: DG.Column<string>): Promise<void> {
|
|
9
|
+
const molCol = await getMolColumnFromHelm(df, helmCol);
|
|
10
|
+
df.columns.add(molCol, true);
|
|
11
|
+
await grok.data.detectSemanticTypes(df);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/** Translate HELM column into molfile column and append to the dataframe */
|
|
16
|
+
export async function getMolColumnFromHelm(
|
|
17
|
+
df: DG.DataFrame, helmCol: DG.Column<string>, chiralityEngine?: boolean
|
|
18
|
+
): Promise<DG.Column<string>> {
|
|
19
|
+
const converter = new HelmToMolfileConverter(helmCol, df);
|
|
20
|
+
const molCol = await converter.convertToRdKitBeautifiedMolfileColumn(chiralityEngine);
|
|
21
|
+
molCol.semType = DG.SEMTYPE.MOLECULE;
|
|
22
|
+
return molCol;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function getSmilesColumnFromHelm(
|
|
26
|
+
df: DG.DataFrame, helmCol: DG.Column<string>
|
|
27
|
+
): Promise<DG.Column<string>> {
|
|
28
|
+
const converter = new HelmToMolfileConverter(helmCol, df);
|
|
29
|
+
const smilesCol = await converter.convertToSmiles();
|
|
30
|
+
smilesCol.semType = DG.SEMTYPE.MOLECULE;
|
|
31
|
+
return smilesCol;
|
|
32
|
+
}
|
|
@@ -6,12 +6,15 @@ import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
|
6
6
|
import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
|
|
7
7
|
import {ALIGNMENT, ALPHABET} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
import {getMolColumnFromHelm} from '../helm-to-molfile';
|
|
9
|
+
import {getMolColumnFromHelm} from '../helm-to-molfile/utils';
|
|
11
10
|
|
|
12
11
|
export const RULES_PATH = 'System:AppData/Bio/polytool-rules/';
|
|
13
12
|
export const RULES_STORAGE_NAME = 'Polytool';
|
|
14
13
|
|
|
14
|
+
const enum HELM_WRAPPER {
|
|
15
|
+
LEFT = 'PEPTIDE1{',
|
|
16
|
+
RIGHT = '}$$$$',
|
|
17
|
+
}
|
|
15
18
|
|
|
16
19
|
type ConnectionData = {
|
|
17
20
|
allPos1: number[],
|
|
@@ -43,19 +46,8 @@ class TransformationCommon {
|
|
|
43
46
|
this.helmColumn = helmColumn;
|
|
44
47
|
}
|
|
45
48
|
|
|
46
|
-
protected
|
|
47
|
-
|
|
48
|
-
if (helm.includes('(1)'))
|
|
49
|
-
isLinkable = true;
|
|
50
|
-
if (helm.includes('(2)'))
|
|
51
|
-
isLinkable = true;
|
|
52
|
-
|
|
53
|
-
return isLinkable;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
protected getLinkedPositions(helm: string, rules: Rule[]): [number, number][] {
|
|
57
|
-
const seq = helm.replace(HELM_WRAPPER.LEFT, '').replace(HELM_WRAPPER.RIGHT, '');
|
|
58
|
-
const monomers = seq.split('.').map((m) => { return m.replace('[', '').replace(']', ''); });
|
|
49
|
+
protected getLinkedPositions(monomers: string[], rules: Rule[]): [number, number][] {
|
|
50
|
+
const monomersNames = monomers.map((m) => { return m.replace('[', '').replace(']', ''); });
|
|
59
51
|
const result: [number, number][] = new Array<[number, number]>(rules.length);
|
|
60
52
|
|
|
61
53
|
for (let i = 0; i < rules.length; i++) {
|
|
@@ -65,35 +57,35 @@ class TransformationCommon {
|
|
|
65
57
|
let firstEntryIndex = -1;
|
|
66
58
|
let secondEntryIndex = -1;
|
|
67
59
|
const add = `(${rules[i].code})`;
|
|
68
|
-
for (let j = 0; j <
|
|
69
|
-
if (
|
|
60
|
+
for (let j = 0; j < monomersNames.length; j++) {
|
|
61
|
+
if (monomersNames[j].includes(add)) {
|
|
70
62
|
if (firstFound) {
|
|
71
|
-
if (firstIsFirst &&
|
|
63
|
+
if (firstIsFirst && monomersNames[j] == rules[i].secondMonomer + add) {
|
|
72
64
|
secondFound = true;
|
|
73
65
|
secondEntryIndex = j;
|
|
74
66
|
break;
|
|
75
|
-
} else if (!firstIsFirst &&
|
|
67
|
+
} else if (!firstIsFirst && monomersNames[j] == rules[i].firstMonomer + add) {
|
|
76
68
|
secondFound = true;
|
|
77
69
|
secondEntryIndex = j;
|
|
78
70
|
break;
|
|
79
|
-
} else
|
|
71
|
+
} else
|
|
80
72
|
continue;
|
|
81
|
-
|
|
73
|
+
|
|
82
74
|
//result[i][1] = j;
|
|
83
75
|
// secondFound = true;
|
|
84
76
|
// break;
|
|
85
77
|
} else {
|
|
86
|
-
if (
|
|
78
|
+
if (monomersNames[j] == rules[i].firstMonomer + add) {
|
|
87
79
|
firstFound = true;
|
|
88
80
|
firstIsFirst = true;
|
|
89
81
|
firstEntryIndex = j;
|
|
90
|
-
} else if (
|
|
82
|
+
} else if (monomersNames[j] == rules[i].secondMonomer + add) {
|
|
91
83
|
firstFound = true;
|
|
92
84
|
firstIsFirst = false;
|
|
93
85
|
firstEntryIndex = j;
|
|
94
|
-
} else
|
|
86
|
+
} else
|
|
95
87
|
continue;
|
|
96
|
-
|
|
88
|
+
|
|
97
89
|
//result[i] = [j, 0];
|
|
98
90
|
}
|
|
99
91
|
}
|
|
@@ -141,22 +133,42 @@ class TransformationCommon {
|
|
|
141
133
|
return rules;
|
|
142
134
|
}
|
|
143
135
|
|
|
144
|
-
protected
|
|
145
|
-
const
|
|
146
|
-
const
|
|
136
|
+
protected getDimeric(helm: string): [string[], [number, number][]] {
|
|
137
|
+
const seq = helm.replace(HELM_WRAPPER.LEFT, '').replace(HELM_WRAPPER.RIGHT, '');
|
|
138
|
+
const monomers = seq.split('.');
|
|
139
|
+
const duplicates: [number, number][] = [];
|
|
140
|
+
|
|
141
|
+
for (let i = 0; i < monomers.length; i++) {
|
|
142
|
+
if (monomers[i].includes('(#2)')) {
|
|
143
|
+
monomers[i] = monomers[i].replace('(#2)', '');
|
|
144
|
+
const duplicateStart = i + 1;
|
|
145
|
+
let duplicateFinish = 0;
|
|
146
|
+
for (let j = duplicateStart + 1; j < monomers.length; j++) {
|
|
147
|
+
if (monomers[j].includes('}')) {
|
|
148
|
+
duplicateFinish = j; break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
monomers[duplicateStart] = monomers[duplicateStart].replace('{', '');
|
|
152
|
+
monomers[duplicateFinish] = monomers[duplicateFinish].replace('}', '');
|
|
153
|
+
duplicates.push([duplicateStart, duplicateFinish]);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return [monomers, duplicates];
|
|
158
|
+
}
|
|
147
159
|
|
|
160
|
+
protected getAllCycles(rules: Rule[], monomers: string [], positions: [number, number][]) :
|
|
161
|
+
[string [], number [], number [], number [], number []] {
|
|
148
162
|
const allPos1: number [] = [];
|
|
149
163
|
const allPos2: number [] = [];
|
|
150
164
|
const allAttaches1: number [] = [];
|
|
151
165
|
const allAttaches2: number [] = [];
|
|
166
|
+
const ruleCount = rules.length;
|
|
152
167
|
|
|
153
168
|
for (let i = 0; i < ruleCount; i++) {
|
|
154
169
|
if (positions[i][0] == -1)
|
|
155
170
|
continue;
|
|
156
171
|
|
|
157
|
-
//helm = helm.replaceAll(`(${i + 1})`, '');
|
|
158
|
-
const seq = helm.replace(HELM_WRAPPER.LEFT, '').replace(HELM_WRAPPER.RIGHT, '');
|
|
159
|
-
const monomers = seq.split('.');
|
|
160
172
|
const firstMonomer = monomers[positions[i][0]].replace('[', '').replace(']', '');
|
|
161
173
|
const secondMonomer = monomers[positions[i][1]].replace('[', '').replace(']', '');
|
|
162
174
|
|
|
@@ -167,31 +179,97 @@ class TransformationCommon {
|
|
|
167
179
|
allPos2.push(positions[i][1] + 1);
|
|
168
180
|
allAttaches1.push(rules[i].firstR);
|
|
169
181
|
allAttaches2.push(rules[i].secondR);
|
|
182
|
+
}
|
|
170
183
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
184
|
+
return [monomers, allPos1, allPos2, allAttaches1, allAttaches2];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
protected getHelmCycle(source: ConnectionData, polFirst: number, poSecond: number): string {
|
|
188
|
+
let cycled = '';
|
|
189
|
+
|
|
190
|
+
for (let i = 0; i < source.allPos1.length; i++) {
|
|
191
|
+
if (i == 0)
|
|
192
|
+
cycled += `PEPTIDE${polFirst},PEPTIDE${poSecond},`;
|
|
193
|
+
else
|
|
194
|
+
cycled += `|PEPTIDE${polFirst},PEPTIDE${poSecond},`;
|
|
195
|
+
cycled += `${source.allPos1[i]}:R${source.allAttaches1[i]}-${source.allPos2[i]}:R${source.allAttaches2[i]}`;
|
|
179
196
|
}
|
|
197
|
+
return cycled;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
//"PEPTIDE1{[(#2)Succ].[{R].F.[Dab(2)].T.G.H.F.G.A.A.Y.P.[E(2)].[NH2}]}$$$$"
|
|
201
|
+
protected getTransformedHelm(helm: string, rules: Rule[]): string {
|
|
202
|
+
const [monomers, duplicates] = this.getDimeric(helm);
|
|
203
|
+
const positions = this.getLinkedPositions(monomers, rules);
|
|
204
|
+
const [monomersCycled, allPos1, allPos2, allAttaches1, allAttaches2] =
|
|
205
|
+
this.getAllCycles(rules, monomers, positions);
|
|
206
|
+
|
|
207
|
+
helm = 'PEPTIDE1{';
|
|
208
|
+
for (let i = 0; i < monomersCycled.length; i++)
|
|
209
|
+
helm += i != monomersCycled.length - 1 ? monomersCycled[i] + '.' : monomersCycled[i];
|
|
210
|
+
|
|
211
|
+
helm += '}';
|
|
212
|
+
|
|
213
|
+
const dimerCodes = new Array<string>(duplicates.length);
|
|
214
|
+
const cycleCodes = new Array<string>(duplicates.length);
|
|
215
|
+
for (let i = 0; i < duplicates.length; i++) {
|
|
216
|
+
let helmAdd = `|PEPTIDE${i + 2}{`;
|
|
217
|
+
const lengthAdd = duplicates[i][1] - duplicates[i][0];
|
|
218
|
+
//const monomersAdd = new Array<string>(lengthAdd);
|
|
219
|
+
const allPosAdd1: number [] = [];
|
|
220
|
+
const allPosAdd2: number [] = [];
|
|
221
|
+
const allAttachesAdd1: number [] = [];
|
|
222
|
+
const allAttachesAdd2: number [] = [];
|
|
223
|
+
|
|
224
|
+
for (let j = 0; j <= lengthAdd; j ++) {
|
|
225
|
+
const index = j + duplicates[i][0];
|
|
226
|
+
helmAdd += j != lengthAdd ? monomersCycled[index] + '.' : monomersCycled[index];
|
|
227
|
+
}
|
|
180
228
|
|
|
229
|
+
helmAdd += '}';
|
|
181
230
|
|
|
182
|
-
|
|
231
|
+
for (let j = 0; j < allPos1.length; j++) {
|
|
232
|
+
if (allPos1[j] - 1 >= duplicates[i][0] && allPos1[j] - 1 <= duplicates[i][1]) {
|
|
233
|
+
allPosAdd1.push(allPos1[j] - duplicates[i][0]);
|
|
234
|
+
allPosAdd2.push(allPos2[j] - duplicates[i][0]);
|
|
235
|
+
allAttachesAdd1.push(allAttaches1[j]);
|
|
236
|
+
allAttachesAdd2.push(allAttaches1[j]);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
183
239
|
|
|
184
|
-
|
|
240
|
+
const addCyclysation = this.getHelmCycle({
|
|
241
|
+
allPos1: allPosAdd1,
|
|
242
|
+
allPos2: allPosAdd2,
|
|
243
|
+
allAttaches1: allAttachesAdd1,
|
|
244
|
+
allAttaches2: allAttachesAdd2}, i + 2, i + 2);
|
|
245
|
+
|
|
246
|
+
dimerCodes[i] = helmAdd;
|
|
247
|
+
cycleCodes[i] = this.getHelmCycle({
|
|
248
|
+
allPos1: [duplicates[i][0]],
|
|
249
|
+
allPos2: [1],
|
|
250
|
+
allAttaches1: [1],
|
|
251
|
+
allAttaches2: [1]}, 1, i + 2);
|
|
252
|
+
cycleCodes.push(addCyclysation);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
for (let i = 0; i < dimerCodes.length; i++)
|
|
256
|
+
helm += dimerCodes[i];
|
|
257
|
+
|
|
258
|
+
helm += '$';
|
|
259
|
+
const mainCyclysation = this.getHelmCycle({allPos1, allPos2, allAttaches1, allAttaches2}, 1, 1);
|
|
260
|
+
helm += mainCyclysation;
|
|
261
|
+
for (let i = 0; i < cycleCodes.length; i++) {
|
|
262
|
+
helm += '|';
|
|
263
|
+
helm += cycleCodes[i];
|
|
264
|
+
}
|
|
265
|
+
helm += '$$$';
|
|
266
|
+
return helm;
|
|
185
267
|
}
|
|
186
268
|
|
|
187
269
|
transform(rulesTables: DG.DataFrame[]): string[] {
|
|
188
270
|
const rules = this.getRules(rulesTables);
|
|
189
271
|
const resultList = this.helmColumn.toList().map((helm: string) => {
|
|
190
|
-
|
|
191
|
-
return this.getTransformedHelm(helm, rules);
|
|
192
|
-
|
|
193
|
-
console.log(helm);
|
|
194
|
-
return helm;
|
|
272
|
+
return this.getTransformedHelm(helm, rules);
|
|
195
273
|
});
|
|
196
274
|
return resultList;
|
|
197
275
|
}
|
|
@@ -205,21 +283,6 @@ class PolymerTransformation {
|
|
|
205
283
|
}
|
|
206
284
|
}
|
|
207
285
|
|
|
208
|
-
function getHelmCycle(helm: string, source: ConnectionData): string {
|
|
209
|
-
let cycled = helm.replace(HELM_WRAPPER.RIGHT, '}$');
|
|
210
|
-
|
|
211
|
-
for (let i = 0; i < source.allPos1.length; i++) {
|
|
212
|
-
if (i == 0)
|
|
213
|
-
cycled += 'PEPTIDE1,PEPTIDE1,';
|
|
214
|
-
else
|
|
215
|
-
cycled += '|PEPTIDE1,PEPTIDE1,';
|
|
216
|
-
cycled += `${source.allPos1[i]}:R${source.allAttaches1[i]}-${source.allPos2[i]}:R${source.allAttaches2[i]}`;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
cycled += '$$$';
|
|
220
|
-
return cycled;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
286
|
export async function addTransformedColumn(
|
|
224
287
|
molColumn: DG.Column<string>, addHelm: boolean, ruleFiles: string[], chiralityEngine?: boolean
|
|
225
288
|
): Promise<void> {
|
|
@@ -249,8 +312,9 @@ export async function addTransformedColumn(
|
|
|
249
312
|
|
|
250
313
|
if (addHelm) {
|
|
251
314
|
targetHelmCol.setTag('cell.renderer', 'helm');
|
|
252
|
-
targetHelmCol.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
315
|
+
//targetHelmCol.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
253
316
|
df.columns.add(targetHelmCol);
|
|
254
317
|
}
|
|
255
318
|
df.columns.add(molCol, true);
|
|
319
|
+
await grok.data.detectSemanticTypes(df);
|
|
256
320
|
}
|
|
@@ -4,7 +4,7 @@ import * as ui from 'datagrok-api/ui';
|
|
|
4
4
|
import * as DG from 'datagrok-api/dg';
|
|
5
5
|
|
|
6
6
|
import {_toAtomicLevel} from '@datagrok-libraries/bio/src/monomer-works/to-atomic-level';
|
|
7
|
-
import {helm2mol} from './helm-to-molfile';
|
|
7
|
+
import {helm2mol} from './helm-to-molfile/utils';
|
|
8
8
|
import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
|
|
9
9
|
import {checkInputColumnUI} from './check-input-column';
|
|
10
10
|
import {getMonomerLibHelper} from '../package';
|
package/webpack.config.js
CHANGED
|
@@ -2,11 +2,12 @@ const path = require('path');
|
|
|
2
2
|
const FuncGeneratorPlugin = require('datagrok-tools/plugins/func-gen-plugin');
|
|
3
3
|
const packageName = path.parse(require('./package.json').name).name.toLowerCase().replace(/-/g, '');
|
|
4
4
|
|
|
5
|
+
const mode = 'development';
|
|
5
6
|
module.exports = {
|
|
6
7
|
cache: {
|
|
7
8
|
type: 'filesystem',
|
|
8
9
|
},
|
|
9
|
-
mode:
|
|
10
|
+
mode: mode,
|
|
10
11
|
entry: {
|
|
11
12
|
package: ['./src/package.ts'],
|
|
12
13
|
test: {
|
|
@@ -29,12 +30,12 @@ module.exports = {
|
|
|
29
30
|
plugins: [
|
|
30
31
|
new FuncGeneratorPlugin({outputPath: './src/package.g.ts'}),
|
|
31
32
|
],
|
|
32
|
-
devtool: 'source-map',
|
|
33
|
+
devtool: mode === 'development' ? 'source-map' : 'inline-source-map',
|
|
33
34
|
externals: {
|
|
34
35
|
'datagrok-api/dg': 'DG',
|
|
35
36
|
'datagrok-api/grok': 'grok',
|
|
36
37
|
'datagrok-api/ui': 'ui',
|
|
37
|
-
'openchemlib/full
|
|
38
|
+
'openchemlib/full': 'OCL',
|
|
38
39
|
'rxjs': 'rxjs',
|
|
39
40
|
'rxjs/operators': 'rxjs.operators',
|
|
40
41
|
'cash-dom': '$',
|
package/dist/709.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var bio;(()=>{"use strict";var t,e,r={2357:(t,e,r)=>{var o=r(2590);async function n(t,e,r){const o=t.length,n=[],s=[];for(let a=0;a<o;a++)for(let l=a+1;l<o;l++){const o=t[a],i=t[l];e[o]?.[i]>=r&&(n.push(a),s.push(l))}return function(t,e,r){const o=new Float32Array(r.length).fill(0).map((()=>10*Math.random())),n=new Float32Array(r.length).fill(0).map((()=>10*Math.random())),s=new Float32Array(r.length).fill(0),a=new Float32Array(r.length).fill(0);for(let l=0;l<100;l++){const i=1-l/100;s.fill(0),a.fill(0);for(let r=0;r<t.length;r++){const l=t[r],c=e[r],f=o[l]-o[c],h=n[l]-n[c];Math.abs(f)>=1&&(s[l]-=i*f,s[c]+=i*f),Math.abs(h)>=1&&(a[l]-=i*h,a[c]+=i*h)}for(let t=0;t<r.length;t++){const e=Math.sqrt(s[t]*s[t]+a[t]*a[t]);e>0&&(o[t]+=s[t]/e*i,n[t]+=a[t]/e*i)}}let l=o[0],i=n[0],c=o[0],f=n[0];for(let t=1;t<r.length;t++)l=Math.min(l,o[t]),i=Math.min(i,n[t]),c=Math.max(c,o[t]),f=Math.max(f,n[t]);let h=c-l,u=f-i;0===h&&(h=c);for(let t=0;t<r.length;t++)o[t]=(o[t]-l)/h/2+.5;0===u&&(u=f);for(let t=0;t<r.length;t++)n[t]=(n[t]-i)/u/2+.5;return{embedX:o,embedY:n}}(n,s,t)}const s={expandFactor:2,maxIterations:5,inflateFactor:2,multFactor:1};class a{constructor(t={}){this._options={...s,...t}}async transform(t,e){let r=this.toObjectForm(t);if(this._options.maxIterations>0){this.addLoops(r,e),this.normalize(r);for(let t=0;t<this._options.maxIterations;t++)r=this.expand(r,e),this.inflate(r),this.normalize(r)}const{clusters:o,is:n,js:s}=this.assignClusters(r,e);this.correctClusters(o);const a=await this.layout(o,r,e);return{clusters:o,embedX:a.embedX,embedY:a.embedY,is:n,js:s}}correctClusters(t){const e={};for(const r of t)e[r]||(e[r]=0),e[r]++;const r=Object.keys(e).map(Number).sort(((t,r)=>e[t]-e[r])),o={};r.forEach(((t,e)=>o[t]=e+1));for(let e=0;e<t.length;e++)t[e]=o[t[e]]}async layout(t,e,r){const o=new Float32Array(r).fill(0),s=new Float32Array(r).fill(0),a={};t.forEach(((t,e)=>{a[t]||(a[t]=[]),a[t].push(e)}));let l=0;const i=Object.keys(a);i.sort(((t,e)=>a[e].length-a[t].length));let c=6,f=0;for(const t of i){const r=a[t],i=await n(r,e,.001);l===Math.ceil(c/1.5)&&(l=0,f+=5/c,c=Math.ceil(1.5*c));const h=l%c*5/c*1.5;for(let t=0;t<i.embedX.length;t++)o[r[t]]=5*i.embedX[t]/c+h,s[r[t]]=5*i.embedY[t]/c+f;l++}return{embedX:o,embedY:s}}mergeClusters(t,e,r){const o=t[e],n=t[r];for(let e=0;e<t.length;e++)t[e]===n&&(t[e]=o)}assignClusters(t,e){let r=0;const o=[],n=[],s=Math.floor(Math.max(Math.log10(e),2))+1,a=Math.pow(10,s),l=new Array(e).fill(-1);for(const e of Object.keys(t))for(const s of Object.keys(t[e]))Math.round(t[e][s]*a)/a>0&&t[e][s]!==Number(e)&&Number(s)>Number(e)&&(o.push(Number(e)),n.push(Number(s)),-1!==l[Number(e)]&&-1!==l[Number(s)]?l[Number(e)]!==l[Number(s)]&&this.mergeClusters(l,Number(e),Number(s)):-1!==l[Number(e)]?l[Number(s)]=l[Number(e)]:-1!==l[Number(s)]?l[Number(e)]=l[Number(s)]:(r++,l[Number(e)]=r,l[Number(s)]=r));for(let t=0;t<l.length;t++)-1===l[t]&&(r++,l[t]=r);return{clusters:l,is:new Uint32Array(o),js:new Uint32Array(n)}}toObjectForm(t){const e={};for(let r=0;r<t.i.length;r++)e[t.i[r]]||(e[t.i[r]]={}),e[t.i[r]][t.j[r]]=1-t.distance[r],e[t.j[r]]||(e[t.j[r]]={}),e[t.j[r]][t.i[r]]=1-t.distance[r];return e}addLoops(t,e){for(let r=0;r<e;r++)t[r]||(t[r]={}),t[r][r]=this._options.multFactor}normalize(t){for(const e of Object.keys(t)){const r=t[e];let o=0;for(const t of Object.keys(r))o+=r[t];if(0!==o)for(const n of Object.keys(r))t[e][n]/=o}}expand(t,e){const r={},o=Math.floor(Math.max(Math.log10(e),2))+1,n=Math.pow(10,o);for(let o=0;o<e;o++)if(t[o]){r[o]={};for(let s=o;s<e;s++){if(!t[o]?.[s])continue;const e=this.getExpandValue(t,o,s);Math.round(e*n)/n>0&&(r[o][s]=e,r[s]||(r[s]={}),r[s][o]=e)}}return r}inflate(t){for(const e of Object.keys(t)){const r=t[e];for(const o of Object.keys(r))t[e][o]=Math.pow(t[e][o],this._options.inflateFactor)}}getExpandValue(t,e,r){let o=0;const n=Object.keys(t[e]??{}),s=Object.keys(t[r]??{});for(const a of n)s.includes(a)&&(o+=t[e][a]*t[r][a]);return o}}onmessage=async t=>{const{data:e,threshold:r,weights:n,aggregationMethod:s,distanceFnArgs:l,distanceFns:i,maxIterations:c}=t.data,f=await(new o._).calcMultiColumn(e,i,r/100,l,n,s),h=await new a({maxIterations:c??5}).transform(f,e[0].length);postMessage({res:h})}},6814:(t,e,r)=>{r.d(e,{cZ:()=>n,kK:()=>o}),r(7862);const o=t=>null==t;function n(t,e,r,o){if(r>t[t.length-1])return;const n=t.findIndex((t=>r<t));t.pop(),t.splice(n,0,r),e.pop(),e.splice(n,0,o)}}},o={};function n(t){var e=o[t];if(void 0!==e)return e.exports;var s=o[t]={exports:{}};return r[t](s,s.exports,n),s.exports}n.m=r,n.x=()=>{var t=n.O(void 0,[590],(()=>n(2357)));return n.O(t)},t=[],n.O=(e,r,o,s)=>{if(!r){var a=1/0;for(f=0;f<t.length;f++){for(var[r,o,s]=t[f],l=!0,i=0;i<r.length;i++)(!1&s||a>=s)&&Object.keys(n.O).every((t=>n.O[t](r[i])))?r.splice(i--,1):(l=!1,s<a&&(a=s));if(l){t.splice(f--,1);var c=o();void 0!==c&&(e=c)}}return e}s=s||0;for(var f=t.length;f>0&&t[f-1][2]>s;f--)t[f]=t[f-1];t[f]=[r,o,s]},n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.f={},n.e=t=>Promise.all(Object.keys(n.f).reduce(((e,r)=>(n.f[r](t,e),e)),[])),n.u=t=>t+".js",n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),(()=>{var t;n.g.importScripts&&(t=n.g.location+"");var e=n.g.document;if(!t&&e&&(e.currentScript&&(t=e.currentScript.src),!t)){var r=e.getElementsByTagName("script");if(r.length)for(var o=r.length-1;o>-1&&!t;)t=r[o--].src}if(!t)throw new Error("Automatic publicPath is not supported in this browser");t=t.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),n.p=t})(),(()=>{n.b=self.location+"";var t={709:1};n.f.i=(e,r)=>{t[e]||importScripts(n.p+n.u(e))};var e=self.webpackChunkbio=self.webpackChunkbio||[],r=e.push.bind(e);e.push=e=>{var[o,s,a]=e;for(var l in s)n.o(s,l)&&(n.m[l]=s[l]);for(a&&a(n);o.length;)t[o.pop()]=1;r(e)}})(),e=n.x,n.x=()=>n.e(590).then(e);var s=n.x();bio=s})();
|
|
2
|
-
//# sourceMappingURL=709.js.map
|