@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.
@@ -1,44 +1,41 @@
1
- [
2
- {
3
- "type": "link",
4
- "code": "1",
5
- "monomericSubstitution": {
6
- "firstMonomer": "C",
7
- "secondMonomer": "C",
8
- "firstLinkingGroup": "3",
9
- "secondLinkingGroup": "3",
10
- "firstSubstitution": "C",
11
- "secondSubstitution": "C"
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
- "firstSubstitution": "NH2",
23
- "secondSubstitution": "D"
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
- "type": "reaction",
28
- "code": "4",
29
- "monomericSubstitution": {
30
- "firstMonomer": "azG",
31
- "secondMonomer": "aG",
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,7 +1,7 @@
1
1
  {
2
2
  "name": "@datagrok/sequence-translator",
3
3
  "friendlyName": "Sequence Translator",
4
- "version": "1.4.10",
4
+ "version": "1.5.0",
5
5
  "author": {
6
6
  "name": "Leonid Stolbov",
7
7
  "email": "lstolbov@datagrok.ai"
@@ -1,10 +1,10 @@
1
- import {Atom, IHelmBio, HelmMol, HelmType, JSDraw2ModuleType, OrgType,} from '@datagrok-libraries/bio/src/helm/types';
2
- import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
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 '../pt-rules';
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][] = new Array<[number, number, number]>(rules.length);
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
- for (let j = 0; j < monomers.length; j++) {
536
- if (monomers[j].includes(add)) {
537
- if (firstFound) {
538
- if (firstIsFirst && monomers[j] == rules[i].secondMonomer + add) {
539
- secondFound = true;
540
- secondEntryIndex = j;
541
- break;
542
- } else if (!firstIsFirst && monomers[j] == rules[i].firstMonomer + add) {
543
- secondFound = true;
544
- secondEntryIndex = j;
545
- break;
546
- } else {
547
- continue;
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
- } else {
550
- if (monomers[j] == rules[i].firstMonomer + add) {
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 = j;
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
- if (!(firstFound && secondFound))
566
- result[i] = [-1, -1, -1];
567
- else if (firstIsFirst)
568
- result[i] = [firstEntryIndex, secondEntryIndex, i];
569
- else
570
- result[i] = [secondEntryIndex, firstEntryIndex, i];
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 ruleCount = rules.length;
618
+ const count = positions.length;
583
619
 
584
- for (let i = 0; i < ruleCount; i++) {
620
+ for (let i = 0; i < count; i++) {
585
621
  if (positions[i][0] == -1)
586
622
  continue;
587
623
 
588
- const firstMonomer = monomers[positions[i][0]];
589
- const secondMonomer = monomers[positions[i][1]];
590
- monomers[positions[i][0]] = monomers[positions[i][0]].replace(firstMonomer, rules[i].firstSubstitution);
591
- monomers[positions[i][1]] = monomers[positions[i][1]].replace(secondMonomer, rules[i].secondSubstitution);
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[i].firstLinkingGroup);
596
- allAttaches2.push(rules[i].secondLinkingGroup);
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 ruleCount = rules.length;
644
+ const count = positions.length;
608
645
 
609
- for (let i = 0; i < ruleCount; i++) {
646
+ for (let i = 0; i < count; i++) {
610
647
  if (positions[i][0] == -1)
611
648
  continue;
612
649
 
613
- const firstMonomer = monomers[positions[i][0]];
614
- const secondMonomer = monomers[positions[i][1]];
615
- monomers[positions[i][0]] = monomers[positions[i][0]].replace(firstMonomer, rules[i].firstMonomer);
616
- monomers[positions[i][1]] = monomers[positions[i][1]].replace(secondMonomer, rules[i].secondMonomer);
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, RuleReaction} from '../pt-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 '../pt-rules';
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 getNewMonomer(rdkit: RDModule, mLib: IMonomerLib, rule: RuleReaction): [string, Monomer] {
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 monomer1 = mLib.getMonomer('PEPTIDE', rule.firstMonomer);
136
- if (!monomer1) throw new MonomerNotFoundError('PEPTIDE', rule.firstMonomer);
137
- const monomer2 = mLib.getMonomer('PEPTIDE', rule.secondMonomer);
138
- if (!monomer2) throw new MonomerNotFoundError('PEPTIDE', rule.secondMonomer);
139
-
140
- const [mb1, mb2] = getMonomersMolBlocks(monomer1!, monomer2!);
141
- const molBlock = getSyntheticMolBlock(rdkit, reacSmarts, mb1, mb2, monomerName);
142
- const groups: RGroup[] = getNewGroups(monomer1!, monomer2!);
143
-
144
- const resMonomer: Monomer = {
145
- [REQ.SYMBOL]: monomerName,
146
- [REQ.NAME]: monomerName,
147
- [REQ.MOLFILE]: molBlock,
148
- [REQ.AUTHOR]: '',
149
- [REQ.ID]: 0,
150
- [REQ.RGROUPS]: groups,
151
- [REQ.SMILES]: '',
152
- [REQ.POLYMER_TYPE]: 'PEPTIDE',
153
- [REQ.MONOMER_TYPE]: 'Backbone',
154
- [REQ.CREATE_DATE]: null,
155
-
156
- // // @ts-ignore
157
- // lib: {source: 'Reaction'},
158
- };
159
-
160
- resMonomer[OPT.META] = Object.assign(resMonomer[OPT.META] ?? {},
161
- {'colors': {'default': {line: '#2083D5', text: '#2083D5', background: '#F2F2F5'}}});
162
-
163
- return [monomerName, resMonomer];
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 [name, monomer] = getNewMonomer(rdkit, systemMonomerLib, rules.reactionRules[i]);
175
- argLib[name] = monomer;
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
+ }