@datagrok/sequence-translator 1.4.10 → 1.5.0
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/CHANGELOG.md +6 -0
- package/dist/package-test.js +1 -1
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/files/polytool-rules/rules_example.json +35 -38
- package/package.json +1 -1
- package/src/polytool/conversion/pt-chain.ts +84 -47
- package/src/polytool/conversion/pt-conversion.ts +1 -2
- package/src/polytool/conversion/pt-misc.ts +43 -33
- package/src/polytool/conversion/pt-rules.ts +231 -0
- package/src/polytool/conversion/rule-manager.ts +205 -0
- package/src/polytool/pt-convert-editor.ts +1 -1
- package/src/polytool/pt-dialog.ts +1 -1
- package/src/polytool/pt-enumerate-seq-dialog.ts +3 -3
- package/src/polytool/pt-unrule-dialog.ts +1 -1
- package/src/polytool/pt-unrule.ts +1 -1
- package/src/tests/polytool-chain-from-notation-tests.ts +6 -14
- package/src/tests/polytool-chain-parse-notation-tests.ts +1 -1
- package/src/tests/polytool-convert-tests.ts +3 -2
- package/src/tests/polytool-unrule-tests.ts +1 -1
- package/src/tests/toAtomicLevel-tests.ts +5 -5
- package/src/polytool/pt-rules.ts +0 -93
|
@@ -1,44 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"type": "link",
|
|
16
|
-
"code": "2",
|
|
17
|
-
"monomericSubstitution": {
|
|
18
|
-
"firstMonomer": "NH2",
|
|
19
|
-
"secondMonomer": "D",
|
|
1
|
+
{
|
|
2
|
+
"homodimerCode": "#2",
|
|
3
|
+
"heterodimerCode": "$2",
|
|
4
|
+
"linkRules": [
|
|
5
|
+
{
|
|
6
|
+
"firstMonomers": [
|
|
7
|
+
"NH2"
|
|
8
|
+
],
|
|
9
|
+
"secondMonomers": [
|
|
10
|
+
"D"
|
|
11
|
+
],
|
|
20
12
|
"firstLinkingGroup": "2",
|
|
21
13
|
"secondLinkingGroup": "3",
|
|
22
|
-
"
|
|
23
|
-
|
|
14
|
+
"code": "2"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"firstMonomers": [
|
|
18
|
+
"C"
|
|
19
|
+
],
|
|
20
|
+
"secondMonomers": [
|
|
21
|
+
"C"
|
|
22
|
+
],
|
|
23
|
+
"firstLinkingGroup": "3",
|
|
24
|
+
"secondLinkingGroup": "3",
|
|
25
|
+
"code": "1"
|
|
24
26
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
],
|
|
28
|
+
"reactionRules": [
|
|
29
|
+
{
|
|
30
|
+
"code": 4,
|
|
31
|
+
"firstMonomers": [
|
|
32
|
+
"azG"
|
|
33
|
+
],
|
|
34
|
+
"secondMonomers": [
|
|
35
|
+
"aG"
|
|
36
|
+
],
|
|
32
37
|
"reaction": "[C:1]N=[N+]=[N-].[C:2]C#C>>[C:1]N1-N=NC=C1[C:2]",
|
|
33
38
|
"name": "GGaz"
|
|
34
39
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"type": "fragmentDuplication",
|
|
38
|
-
"code": "#3"
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
"type": "differentFragments",
|
|
42
|
-
"code": "$3"
|
|
43
|
-
}
|
|
44
|
-
]
|
|
40
|
+
]
|
|
41
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {Atom, IHelmBio, HelmMol, HelmType, JSDraw2ModuleType, OrgType
|
|
2
|
-
import {
|
|
1
|
+
import {Atom, IHelmBio, HelmMol, HelmType, JSDraw2ModuleType, OrgType} from '@datagrok-libraries/bio/src/helm/types';
|
|
2
|
+
import {IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
3
3
|
import {HelmTypes} from '@datagrok-libraries/bio/src/helm/consts';
|
|
4
4
|
import {cleanupHelmSymbol} from '@datagrok-libraries/bio/src/helm/utils';
|
|
5
5
|
|
|
6
6
|
import {getOuterIdx, getInnerIdx} from './pt-misc';
|
|
7
|
-
import {Rules, RuleLink, RuleReaction} from '
|
|
7
|
+
import {Rules, RuleLink, RuleReaction, getMonomerPairs} from './pt-rules';
|
|
8
8
|
|
|
9
9
|
declare const JSDraw2: JSDraw2ModuleType;
|
|
10
10
|
declare const org: OrgType;
|
|
@@ -523,7 +523,7 @@ export class Chain {
|
|
|
523
523
|
|
|
524
524
|
protected static getLinkedPositions(monomers: string[], rules: RuleLink[] | RuleReaction []):
|
|
525
525
|
[number, number, number][] {
|
|
526
|
-
const result: [number, number, number][] =
|
|
526
|
+
const result: [number, number, number][] = [];
|
|
527
527
|
|
|
528
528
|
for (let i = 0; i < rules.length; i++) {
|
|
529
529
|
let firstFound = false;
|
|
@@ -532,42 +532,78 @@ export class Chain {
|
|
|
532
532
|
let firstEntryIndex = -1;
|
|
533
533
|
let secondEntryIndex = -1;
|
|
534
534
|
const add = `(${rules[i].code})`;
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
535
|
+
|
|
536
|
+
const [firstMonomers, secondMonomers] = getMonomerPairs(rules[i]);
|
|
537
|
+
|
|
538
|
+
if (firstMonomers.length > 0) {
|
|
539
|
+
for (let j = 0; j < firstMonomers.length; j++) {
|
|
540
|
+
for (let k = 0; k < monomers.length; k++) {
|
|
541
|
+
if (monomers[k].includes(add)) {
|
|
542
|
+
if (firstFound) {
|
|
543
|
+
if (firstIsFirst && monomers[k] == secondMonomers[j] + add) {
|
|
544
|
+
secondFound = true;
|
|
545
|
+
secondEntryIndex = k;
|
|
546
|
+
break;
|
|
547
|
+
} else if (!firstIsFirst && monomers[k] == firstMonomers[j] + add) {
|
|
548
|
+
secondFound = true;
|
|
549
|
+
secondEntryIndex = k;
|
|
550
|
+
break;
|
|
551
|
+
} else {
|
|
552
|
+
continue;
|
|
553
|
+
}
|
|
554
|
+
} else {
|
|
555
|
+
if (monomers[k] == firstMonomers[j] + add) {
|
|
556
|
+
firstFound = true;
|
|
557
|
+
firstIsFirst = true;
|
|
558
|
+
firstEntryIndex = k;
|
|
559
|
+
} else if (monomers[k] == secondMonomers[j] + add) {
|
|
560
|
+
firstFound = true;
|
|
561
|
+
firstIsFirst = false;
|
|
562
|
+
firstEntryIndex = k;
|
|
563
|
+
} else {
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
548
567
|
}
|
|
549
|
-
}
|
|
550
|
-
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
if (!(firstFound && secondFound))
|
|
571
|
+
continue;
|
|
572
|
+
else if (firstIsFirst)
|
|
573
|
+
result.push([firstEntryIndex, secondEntryIndex, i]);
|
|
574
|
+
else
|
|
575
|
+
result.push([secondEntryIndex, firstEntryIndex, i]);
|
|
576
|
+
}
|
|
577
|
+
} else {
|
|
578
|
+
for (let k = 0; k < monomers.length; k++) {
|
|
579
|
+
if (monomers[k].includes(add)) {
|
|
580
|
+
if (firstFound) {
|
|
581
|
+
if (firstIsFirst && monomers[k]) {
|
|
582
|
+
secondFound = true;
|
|
583
|
+
secondEntryIndex = k;
|
|
584
|
+
break;
|
|
585
|
+
} else if (!firstIsFirst && monomers[k]) {
|
|
586
|
+
secondFound = true;
|
|
587
|
+
secondEntryIndex = k;
|
|
588
|
+
break;
|
|
589
|
+
} else {
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
} else {
|
|
551
593
|
firstFound = true;
|
|
552
594
|
firstIsFirst = true;
|
|
553
|
-
firstEntryIndex =
|
|
554
|
-
} else if (monomers[j] == rules[i].secondMonomer + add) {
|
|
555
|
-
firstFound = true;
|
|
556
|
-
firstIsFirst = false;
|
|
557
|
-
firstEntryIndex = j;
|
|
558
|
-
} else {
|
|
559
|
-
continue;
|
|
595
|
+
firstEntryIndex = k;
|
|
560
596
|
}
|
|
561
597
|
}
|
|
562
598
|
}
|
|
563
|
-
}
|
|
564
599
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
600
|
+
if (!(firstFound && secondFound))
|
|
601
|
+
continue;
|
|
602
|
+
else if (firstIsFirst)
|
|
603
|
+
result.push([firstEntryIndex, secondEntryIndex, i]);
|
|
604
|
+
else
|
|
605
|
+
result.push([secondEntryIndex, firstEntryIndex, i]);
|
|
606
|
+
}
|
|
571
607
|
}
|
|
572
608
|
|
|
573
609
|
return result;
|
|
@@ -579,21 +615,22 @@ export class Chain {
|
|
|
579
615
|
const allPos2: number [] = [];
|
|
580
616
|
const allAttaches1: number [] = [];
|
|
581
617
|
const allAttaches2: number [] = [];
|
|
582
|
-
const
|
|
618
|
+
const count = positions.length;
|
|
583
619
|
|
|
584
|
-
for (let i = 0; i <
|
|
620
|
+
for (let i = 0; i < count; i++) {
|
|
585
621
|
if (positions[i][0] == -1)
|
|
586
622
|
continue;
|
|
587
623
|
|
|
588
|
-
const
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
monomers[positions[i][
|
|
624
|
+
const ruleNum = positions [i][2];
|
|
625
|
+
const code = rules[ruleNum].code;
|
|
626
|
+
|
|
627
|
+
monomers[positions[i][0]] = monomers[positions[i][0]].replace(`(${code})`, '');
|
|
628
|
+
monomers[positions[i][1]] = monomers[positions[i][1]].replace(`(${code})`, '');
|
|
592
629
|
|
|
593
630
|
allPos1.push(positions[i][0] + 1);
|
|
594
631
|
allPos2.push(positions[i][1] + 1);
|
|
595
|
-
allAttaches1.push(rules[
|
|
596
|
-
allAttaches2.push(rules[
|
|
632
|
+
allAttaches1.push(rules[ruleNum].firstLinkingGroup);
|
|
633
|
+
allAttaches2.push(rules[ruleNum].secondLinkingGroup);
|
|
597
634
|
}
|
|
598
635
|
|
|
599
636
|
return [monomers, allPos1, allPos2, allAttaches1, allAttaches2];
|
|
@@ -604,16 +641,16 @@ export class Chain {
|
|
|
604
641
|
const allPos1: number [] = [];
|
|
605
642
|
const allPos2: number [] = [];
|
|
606
643
|
const rule: number [] = [];
|
|
607
|
-
const
|
|
644
|
+
const count = positions.length;
|
|
608
645
|
|
|
609
|
-
for (let i = 0; i <
|
|
646
|
+
for (let i = 0; i < count; i++) {
|
|
610
647
|
if (positions[i][0] == -1)
|
|
611
648
|
continue;
|
|
612
649
|
|
|
613
|
-
const
|
|
614
|
-
const
|
|
615
|
-
monomers[positions[i][0]] = monomers[positions[i][0]].replace(
|
|
616
|
-
monomers[positions[i][1]] = monomers[positions[i][1]].replace(
|
|
650
|
+
const ruleNum = positions [i][2];
|
|
651
|
+
const code = rules[ruleNum].code;
|
|
652
|
+
monomers[positions[i][0]] = monomers[positions[i][0]].replace(`(${code})`, '');
|
|
653
|
+
monomers[positions[i][1]] = monomers[positions[i][1]].replace(`(${code})`, '');
|
|
617
654
|
|
|
618
655
|
allPos1.push(positions[i][0] + 1);
|
|
619
656
|
allPos2.push(positions[i][1] + 1);
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
3
3
|
import {IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
4
4
|
|
|
5
|
-
import {Rules
|
|
6
|
-
import {InvalidReactionError, MonomerNotFoundError} from '../types';
|
|
5
|
+
import {Rules} from './pt-rules';
|
|
7
6
|
import {Chain} from './pt-chain';
|
|
8
7
|
|
|
9
8
|
import {_package} from '../../package';
|
|
@@ -8,7 +8,7 @@ import {RDModule, RDMol, RDReaction, MolList, RDReactionResult} from '@datagrok-
|
|
|
8
8
|
import {HELM_REQUIRED_FIELD as REQ,
|
|
9
9
|
HELM_OPTIONAL_FIELDS as OPT, HELM_RGROUP_FIELDS} from '@datagrok-libraries/bio/src/utils/const';
|
|
10
10
|
import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
|
|
11
|
-
import {Rules, RuleReaction} from '
|
|
11
|
+
import {Rules, RuleReaction, getMonomerPairs} from './pt-rules';
|
|
12
12
|
import {InvalidReactionError, MonomerNotFoundError} from '../types';
|
|
13
13
|
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
14
14
|
|
|
@@ -128,39 +128,48 @@ function getNewGroups(monomer1: Monomer, monomer2: Monomer): RGroup[] {
|
|
|
128
128
|
return groups;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
export function
|
|
131
|
+
export function getNewMonomers(rdkit: RDModule, mLib: IMonomerLib, rule: RuleReaction): [string[], Monomer[]] {
|
|
132
132
|
const reacSmarts = rule.reaction;
|
|
133
133
|
const monomerName = rule.name;
|
|
134
134
|
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
const
|
|
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
|
-
|
|
135
|
+
const [firstMonomers, secondMonomers] = getMonomerPairs(rule);
|
|
136
|
+
|
|
137
|
+
const monomerNames = new Array<string>(firstMonomers.length);
|
|
138
|
+
const resMonomers = new Array<Monomer>(firstMonomers.length);
|
|
139
|
+
|
|
140
|
+
for (let i = 0; i < firstMonomers.length; i ++) {
|
|
141
|
+
const monomer1 = mLib.getMonomer('PEPTIDE', firstMonomers[i]);
|
|
142
|
+
if (!monomer1) throw new MonomerNotFoundError('PEPTIDE', firstMonomers[i]);
|
|
143
|
+
const monomer2 = mLib.getMonomer('PEPTIDE', secondMonomers[i]);
|
|
144
|
+
if (!monomer2) throw new MonomerNotFoundError('PEPTIDE', secondMonomers[i]);
|
|
145
|
+
|
|
146
|
+
const [mb1, mb2] = getMonomersMolBlocks(monomer1!, monomer2!);
|
|
147
|
+
const molBlock = getSyntheticMolBlock(rdkit, reacSmarts, mb1, mb2, monomerName);
|
|
148
|
+
const groups: RGroup[] = getNewGroups(monomer1!, monomer2!);
|
|
149
|
+
|
|
150
|
+
const resMonomer: Monomer = {
|
|
151
|
+
[REQ.SYMBOL]: monomerName,
|
|
152
|
+
[REQ.NAME]: monomerName,
|
|
153
|
+
[REQ.MOLFILE]: molBlock,
|
|
154
|
+
[REQ.AUTHOR]: '',
|
|
155
|
+
[REQ.ID]: 0,
|
|
156
|
+
[REQ.RGROUPS]: groups,
|
|
157
|
+
[REQ.SMILES]: '',
|
|
158
|
+
[REQ.POLYMER_TYPE]: 'PEPTIDE',
|
|
159
|
+
[REQ.MONOMER_TYPE]: 'Backbone',
|
|
160
|
+
[REQ.CREATE_DATE]: null,
|
|
161
|
+
// // @ts-ignore
|
|
162
|
+
// lib: {source: 'Reaction'},
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
resMonomer[OPT.META] = Object.assign(resMonomer[OPT.META] ?? {},
|
|
166
|
+
{'colors': {'default': {line: '#2083D5', text: '#2083D5', background: '#F2F2F5'}}});
|
|
167
|
+
|
|
168
|
+
monomerNames[i] = monomerName;
|
|
169
|
+
resMonomers[i] = resMonomer;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return [monomerNames, resMonomers];
|
|
164
173
|
}
|
|
165
174
|
|
|
166
175
|
export async function getOverriddenLibrary(rules: Rules): Promise<IMonomerLibBase> {
|
|
@@ -171,8 +180,9 @@ export async function getOverriddenLibrary(rules: Rules): Promise<IMonomerLibBas
|
|
|
171
180
|
const argLib: { [symbol: string]: Monomer } = {};
|
|
172
181
|
|
|
173
182
|
for (let i = 0; i < rules.reactionRules.length; i++) {
|
|
174
|
-
const [
|
|
175
|
-
|
|
183
|
+
const [names, monomers] = getNewMonomers(rdkit, systemMonomerLib, rules.reactionRules[i]);
|
|
184
|
+
for (let j = 0; j < names.length; j ++)
|
|
185
|
+
argLib[names[j]] = monomers[j];
|
|
176
186
|
}
|
|
177
187
|
|
|
178
188
|
const overrideMonomerLibData: MonomerLibData = {[PolymerTypes.PEPTIDE]: argLib};
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import * as DG from 'datagrok-api/dg';
|
|
2
|
+
import * as grok from 'datagrok-api/grok';
|
|
3
|
+
import {ActiveFiles} from '@datagrok-libraries/utils/src/settings/active-files-base';
|
|
4
|
+
import {RulesManager} from './rule-manager';
|
|
5
|
+
|
|
6
|
+
export const RULES_PATH = 'System:AppData/SequenceTranslator/polytool-rules/';
|
|
7
|
+
export const RULES_STORAGE_NAME = 'Polytool';
|
|
8
|
+
export const RULES_TYPE_LINK = 'link';
|
|
9
|
+
export const RULES_TYPE_REACTION = 'reaction';
|
|
10
|
+
export const RULES_TYPE_HOMODIMER = 'fragmentDuplication';
|
|
11
|
+
export const RULES_TYPE_HETERODIMER = 'differentFragments';
|
|
12
|
+
|
|
13
|
+
const NAME_CODE = 'code';
|
|
14
|
+
const NAME_FIRST_MONOMERS = 'firstMonomers';
|
|
15
|
+
const NAME_SECOND_MONOMERS = 'secondMonomers';
|
|
16
|
+
const NAME_REACTION_NAME = 'name';
|
|
17
|
+
const NAME_FIRST_LINK = 'firstLinkingGroup';
|
|
18
|
+
const NAME_SECOND_LINK = 'secondLinkingGroup';
|
|
19
|
+
|
|
20
|
+
export class RuleInputs extends ActiveFiles {
|
|
21
|
+
constructor(
|
|
22
|
+
path: string, userStorageName: string, ext: string,
|
|
23
|
+
options?: { onValueChanged: (value: string[]) => void }
|
|
24
|
+
) {
|
|
25
|
+
super(path, userStorageName, ext, options);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
override createInput(available: string, isChecked: boolean): DG.InputBase<boolean> {
|
|
29
|
+
const res = super.createInput(available, isChecked);
|
|
30
|
+
|
|
31
|
+
const editIcon = ui.icons.edit(async () => {
|
|
32
|
+
const rulesManager = await RulesManager.getInstance(available);
|
|
33
|
+
//await rulesManager.show();
|
|
34
|
+
grok.shell.addView(await rulesManager.getView());
|
|
35
|
+
}, 'Edit rules');
|
|
36
|
+
|
|
37
|
+
res.addOptions(editIcon);
|
|
38
|
+
|
|
39
|
+
return res;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type RuleLink = {
|
|
44
|
+
code: number,
|
|
45
|
+
firstMonomers: string[],
|
|
46
|
+
secondMonomers: string[],
|
|
47
|
+
firstLinkingGroup: number,
|
|
48
|
+
secondLinkingGroup: number
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type RuleReaction = {
|
|
52
|
+
code: number,
|
|
53
|
+
firstMonomers: string[],
|
|
54
|
+
secondMonomers: string[],
|
|
55
|
+
reaction: string,
|
|
56
|
+
name: string
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export class Rules {
|
|
60
|
+
homodimerCode: string | null;
|
|
61
|
+
heterodimerCode: string | null;
|
|
62
|
+
linkRules: RuleLink[];
|
|
63
|
+
reactionRules: RuleReaction[];
|
|
64
|
+
|
|
65
|
+
constructor(homodimerCode: string | null, heterodimerCode: string | null,
|
|
66
|
+
linkRules: RuleLink[], reactionRules: RuleReaction[]) {
|
|
67
|
+
this.homodimerCode = homodimerCode;
|
|
68
|
+
this.heterodimerCode = heterodimerCode;
|
|
69
|
+
this.linkRules = linkRules;
|
|
70
|
+
this.reactionRules = reactionRules;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
set homodimer(code: string) {
|
|
74
|
+
this.homodimerCode = code;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
set heterodimer(code: string) {
|
|
78
|
+
this.heterodimerCode = code;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
addLinkRules(rules: RuleLink[]): void {
|
|
82
|
+
for (let j = 0; j < rules.length; j++)
|
|
83
|
+
this.linkRules.push(rules[j]);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
addSynthesisRules(rules: RuleReaction[]): void {
|
|
87
|
+
for (let j = 0; j < rules.length; j++)
|
|
88
|
+
this.reactionRules.push(rules[j]);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
getLinkRulesDf(): DG.DataFrame {
|
|
92
|
+
const length = this.linkRules.length;
|
|
93
|
+
const codeCol = DG.Column.int(NAME_CODE, length);
|
|
94
|
+
const firstMonomerCol = DG.Column.string(NAME_FIRST_MONOMERS, length);
|
|
95
|
+
const secondMonomerCol = DG.Column.string(NAME_SECOND_MONOMERS, length);
|
|
96
|
+
const firstLinkingGroup = DG.Column.int(NAME_FIRST_LINK, length);
|
|
97
|
+
const secondLinkingGroup = DG.Column.int(NAME_SECOND_LINK, length);
|
|
98
|
+
|
|
99
|
+
for (let i = 0; i < length; i++) {
|
|
100
|
+
codeCol.set(i, this.linkRules[i].code);
|
|
101
|
+
firstMonomerCol.set(i, this.linkRules[i].firstMonomers.toString());
|
|
102
|
+
secondMonomerCol.set(i, this.linkRules[i].secondMonomers.toString());
|
|
103
|
+
firstLinkingGroup.set(i, this.linkRules[i].firstLinkingGroup);
|
|
104
|
+
secondLinkingGroup.set(i, this.linkRules[i].secondLinkingGroup);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return DG.DataFrame.fromColumns([
|
|
108
|
+
codeCol, firstMonomerCol, secondMonomerCol, firstLinkingGroup, secondLinkingGroup
|
|
109
|
+
]);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
getSynthesisRulesDf(): DG.DataFrame {
|
|
113
|
+
const length = this.reactionRules.length;
|
|
114
|
+
const codeCol = DG.Column.int(NAME_CODE, length);
|
|
115
|
+
const firstMonomerCol = DG.Column.string(NAME_FIRST_MONOMERS, length);
|
|
116
|
+
const secondMonomerCol = DG.Column.string(NAME_SECOND_MONOMERS, length);
|
|
117
|
+
const name = DG.Column.string(NAME_REACTION_NAME, length);
|
|
118
|
+
const firstReactant = DG.Column.string('firstReactant', length);
|
|
119
|
+
const secondReactant = DG.Column.string('secondReactant', length);
|
|
120
|
+
const product = DG.Column.string('product', length);
|
|
121
|
+
|
|
122
|
+
for (let i = 0; i < length; i++) {
|
|
123
|
+
codeCol.set(i, this.reactionRules[i].code);
|
|
124
|
+
firstMonomerCol.set(i, this.reactionRules[i].firstMonomers.toString());
|
|
125
|
+
secondMonomerCol.set(i, this.reactionRules[i].secondMonomers.toString());
|
|
126
|
+
name.set(i, this.reactionRules[i].name);
|
|
127
|
+
|
|
128
|
+
const reaction = this.reactionRules[i].reaction.split('>>');
|
|
129
|
+
const reactants = reaction[0].split('.');
|
|
130
|
+
|
|
131
|
+
firstReactant.set(i, reactants[0]);
|
|
132
|
+
secondReactant.set(i, reactants[1]);
|
|
133
|
+
product.set(i, reaction[1]);
|
|
134
|
+
}
|
|
135
|
+
firstReactant.semType = DG.SEMTYPE.MOLECULE;
|
|
136
|
+
secondReactant.semType = DG.SEMTYPE.MOLECULE;
|
|
137
|
+
product.semType = DG.SEMTYPE.MOLECULE;
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
return DG.DataFrame.fromColumns([
|
|
141
|
+
name, firstReactant, secondReactant, product, codeCol, firstMonomerCol, secondMonomerCol
|
|
142
|
+
]);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
setLinkRules(df: DG.DataFrame) : void {
|
|
146
|
+
const length = df.rowCount;
|
|
147
|
+
const rules: RuleLink [] = new Array<RuleLink>(length);
|
|
148
|
+
const codeCol = df.columns.byName(NAME_CODE);
|
|
149
|
+
const firstMonomerCol = df.columns.byName(NAME_FIRST_MONOMERS);
|
|
150
|
+
const secondMonomerCol = df.columns.byName(NAME_SECOND_MONOMERS);
|
|
151
|
+
const firstLink = df.columns.byName(NAME_FIRST_LINK);
|
|
152
|
+
const secondLink = df.columns.byName(NAME_SECOND_LINK);
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
for (let i = 0; i < length; i++) {
|
|
156
|
+
const rule = {
|
|
157
|
+
code: codeCol.get(i),
|
|
158
|
+
firstMonomers: firstMonomerCol.get(i).split(','),
|
|
159
|
+
secondMonomers: secondMonomerCol.get(i).split(','),
|
|
160
|
+
firstLinkingGroup: firstLink.get(i),
|
|
161
|
+
secondLinkingGroup: secondLink.get(i)
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
rules[i] = rule;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
this.linkRules = rules;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
setSynthesisRules(df: DG.DataFrame) : void {
|
|
171
|
+
const length = df.rowCount;
|
|
172
|
+
const rules: RuleReaction [] = new Array<RuleReaction>(length);
|
|
173
|
+
const codeCol = df.columns.byName(NAME_CODE);
|
|
174
|
+
const firstMonomerCol = df.columns.byName(NAME_FIRST_MONOMERS);
|
|
175
|
+
const secondMonomerCol = df.columns.byName(NAME_SECOND_MONOMERS);
|
|
176
|
+
const name = df.columns.byName(NAME_REACTION_NAME);
|
|
177
|
+
const firstReactant = df.columns.byName('firstReactant');
|
|
178
|
+
const secondReactant = df.columns.byName('secondReactant');
|
|
179
|
+
const product = df.columns.byName('product');
|
|
180
|
+
|
|
181
|
+
for (let i = 0; i < length; i++) {
|
|
182
|
+
const smartsReaction = `${firstReactant.get(i)}.${secondReactant.get(i)}>>${product.get(i)}`;
|
|
183
|
+
|
|
184
|
+
const rule = {
|
|
185
|
+
code: codeCol.get(i),
|
|
186
|
+
firstMonomers: firstMonomerCol.get(i).split(','),
|
|
187
|
+
secondMonomers: secondMonomerCol.get(i).split(','),
|
|
188
|
+
reaction: smartsReaction,
|
|
189
|
+
name: name.get(i)
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
rules[i] = rule;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
this.reactionRules = rules;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export async function getRules(ruleFiles: string[]): Promise<Rules> {
|
|
200
|
+
const fileSource = new DG.FileSource(RULES_PATH);
|
|
201
|
+
const rules: Rules = new Rules(null, null, [], []);
|
|
202
|
+
|
|
203
|
+
for (let i = 0; i < ruleFiles.length; i++) {
|
|
204
|
+
const rulesRaw = await fileSource.readAsText(ruleFiles[i].replace(RULES_PATH, ''));
|
|
205
|
+
const ruleSingle : Rules = JSON.parse(rulesRaw);
|
|
206
|
+
|
|
207
|
+
rules.homodimer = ruleSingle.homodimerCode!;
|
|
208
|
+
rules.heterodimer = ruleSingle.heterodimerCode!;
|
|
209
|
+
rules.addLinkRules(ruleSingle.linkRules);
|
|
210
|
+
rules.addSynthesisRules(ruleSingle.reactionRules);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return rules;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export function getMonomerPairs(rule: RuleLink | RuleReaction) : [string[], string[]] {
|
|
217
|
+
const allPairsNum = rule.firstMonomers.length*rule.secondMonomers.length;
|
|
218
|
+
const firstMonomers = new Array<string>(allPairsNum);
|
|
219
|
+
const secondMonomers = new Array<string>(allPairsNum);
|
|
220
|
+
|
|
221
|
+
let counter = 0;
|
|
222
|
+
for (let i = 0; i < rule.firstMonomers.length; i++) {
|
|
223
|
+
for (let j = 0; j < rule.secondMonomers.length; j++) {
|
|
224
|
+
firstMonomers[counter] = rule.firstMonomers[i];
|
|
225
|
+
secondMonomers[counter] = rule.secondMonomers[j];
|
|
226
|
+
counter++;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return [firstMonomers, secondMonomers];
|
|
231
|
+
}
|