@datagrok/sequence-translator 1.4.0 → 1.4.2

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.
@@ -10,7 +10,7 @@ import {
10
10
 
11
11
  import {Chain} from './pt-conversion';
12
12
  import {getAvailableMonomers} from './utils';
13
- import {PolyToolEnumeratorParams, PolyToolEnumeratorTypes, PolyToolPlaceholders} from './types';
13
+ import {PolyToolEnumeratorParams, PolyToolEnumeratorTypes, PolyToolPlaceholders, PolyToolPlaceholdersBreadth} from './types';
14
14
 
15
15
  // For example keep monomers presented in HELMCoreLibrary.json only (not [NH2])
16
16
  export const PT_HELM_EXAMPLE = 'PEPTIDE1{R.[Aca].T.G.H.F.G.A.A.Y.P.E.[meI]}$$$$';
@@ -19,17 +19,21 @@ export const PT_HELM_EXAMPLE = 'PEPTIDE1{R.[Aca].T.G.H.F.G.A.A.Y.P.E.[meI]}$$$$'
19
19
  declare const JSDraw2: JSDraw2ModuleType;
20
20
  declare const org: OrgType;
21
21
 
22
- function polyToolEnumeratorCore(m: HelmMol, position: number, monomerList: string[]): HelmMol[] {
23
- const resMolList: HelmMol[] = new Array<HelmMol>(monomerList.length);
24
- for (let i = 0; i < monomerList.length; i++) {
25
- const newSymbol = monomerList[i];
26
- const resM = resMolList[i] = m.clone() as HelmMol;
27
- const oldSymbol = resM.atoms[position].elem;
28
- resM.atoms[position].elem = newSymbol;
22
+ function polyToolEnumeratorCore(m: HelmMol, start: number, end: number, monomerList: string[]): HelmMol[] {
23
+ const resMolList: HelmMol[] = new Array<HelmMol>(monomerList.length * (end - start + 1));
24
+ for (let monI: number = 0; monI < monomerList.length; ++monI) {
25
+ const posCount = end - start + 1;
26
+ for (let posI: number = 0; posI < posCount; ++posI) {
27
+ const pos = start + posI;
28
+ const newSymbol = monomerList[monI];
29
+ const resM = resMolList[monI * posCount + posI] = m.clone() as HelmMol;
30
+ const oldSymbol = resM.atoms[pos].elem;
31
+ resM.atoms[pos].elem = newSymbol;
29
32
 
30
- const idOldSymbol = oldSymbol?.length > 1 ? `[${oldSymbol}]` : oldSymbol;
31
- const idNewSymbol = newSymbol?.length > 1 ? `[${newSymbol}]` : newSymbol;
32
- resM.name = `${m.name}-${idOldSymbol}${position + 1}${idNewSymbol}`;
33
+ const idOldSymbol = oldSymbol?.length > 1 ? `[${oldSymbol}]` : oldSymbol;
34
+ const idNewSymbol = newSymbol?.length > 1 ? `[${newSymbol}]` : newSymbol;
35
+ resM.name = `${m.name}-${idOldSymbol}${pos + 1}${idNewSymbol}`;
36
+ }
33
37
  }
34
38
  return resMolList;
35
39
  }
@@ -40,18 +44,26 @@ function polyToolEnumeratorCore(m: HelmMol, position: number, monomerList: strin
40
44
  * @returns {string[]} List of enumerated molecules in Helm format
41
45
  */
42
46
  function getPtEnumeratorSingle(m: HelmMol, placeholders: PolyToolPlaceholders): HelmMol[] {
43
- const coreResList: HelmMol[][] = Object.entries(placeholders)
44
- .map(([p, monomerList]: [string, string[]]) => polyToolEnumeratorCore(m, parseInt(p), monomerList));
47
+ const coreResList: HelmMol[][] = placeholders
48
+ .map((ph) => polyToolEnumeratorCore(m, ph.position, ph.position, ph.monomers));
45
49
  const resMolList = coreResList.reduce((acc, posList) => acc.concat(posList), []);
46
50
  return resMolList;
47
51
  }
48
52
 
49
53
  function getPtEnumeratorMatrix(m: HelmMol, placeholders: PolyToolPlaceholders): HelmMol[] {
50
54
  let resMolList = [m];
51
- for (const [p, monomerList] of Object.entries(placeholders)) {
52
- const pos: number = parseInt(p);
53
- const posResMolList: HelmMol[][] = resMolList.map((m: HelmMol) => polyToolEnumeratorCore(m, pos, monomerList));
54
- resMolList = posResMolList.reduce((acc, l) => acc.concat(l), []);
55
+ for (const ph of placeholders) {
56
+ const phResMolList: HelmMol[][] = resMolList.map((m: HelmMol) => polyToolEnumeratorCore(m, ph.position, ph.position, ph.monomers));
57
+ resMolList = phResMolList.reduce((acc, l) => acc.concat(l), []);
58
+ }
59
+ return resMolList;
60
+ }
61
+
62
+ function getPtEnumeratorBreadth(m: HelmMol, placeholdersBreadth: PolyToolPlaceholdersBreadth): HelmMol[] {
63
+ let resMolList = [m];
64
+ for (const phb of placeholdersBreadth) {
65
+ const phResMolList: HelmMol[][] = resMolList.map((m: HelmMol) => polyToolEnumeratorCore(m, phb.start, phb.end, phb.monomers));
66
+ resMolList = phResMolList.reduce((acc, l) => acc.concat(l), []);
55
67
  }
56
68
  return resMolList;
57
69
  }
@@ -66,17 +78,25 @@ export function doPolyToolEnumerateHelm(
66
78
  const m = molHandler.m;
67
79
  m.name = id;
68
80
 
69
- let resMolList: HelmMol[];
70
- switch (params.type) {
71
- case PolyToolEnumeratorTypes.Single: {
72
- resMolList = getPtEnumeratorSingle(molHandler.m, params.placeholders);
73
- break;
74
- }
75
- case PolyToolEnumeratorTypes.Matrix: {
76
- resMolList = getPtEnumeratorMatrix(molHandler.m, params.placeholders);
77
- break;
81
+ let resMolList: HelmMol[] = [];
82
+ if (params.placeholders) {
83
+ switch (params.type) {
84
+ case PolyToolEnumeratorTypes.Single: {
85
+ resMolList = getPtEnumeratorSingle(molHandler.m, params.placeholders);
86
+ break;
87
+ }
88
+ case PolyToolEnumeratorTypes.Matrix: {
89
+ resMolList = getPtEnumeratorMatrix(molHandler.m, params.placeholders);
90
+ break;
91
+ }
92
+ }
78
93
  }
94
+
95
+ let resBreadthMolList: HelmMol[] = [];
96
+ if (params.placeholdersBreadth) {
97
+ resBreadthMolList = getPtEnumeratorBreadth(molHandler.m, params.placeholdersBreadth);
79
98
  }
99
+ resMolList = resMolList.concat(resBreadthMolList);
80
100
 
81
101
  if (params.keepOriginal)
82
102
  resMolList = [m, ...resMolList];
@@ -0,0 +1,111 @@
1
+ import * as ui from 'datagrok-api/ui';
2
+ import * as grok from 'datagrok-api/grok';
3
+ import * as DG from 'datagrok-api/dg';
4
+
5
+ import {Unsubscribable} from 'rxjs';
6
+ import {PolyToolPlaceholders, PolyToolPlaceholdersBreadth} from './types';
7
+ import {parseMonomerSymbolList} from './pt-placeholders-input';
8
+
9
+ export class PolyToolPlaceholdersBreadthInput extends DG.JsInputBase<DG.DataFrame> {
10
+ get inputType(): string { return 'Breadth'; }
11
+
12
+ get dataType(): string { return DG.TYPE.DATA_FRAME; }
13
+
14
+ getInput(): HTMLElement { return this.gridHost; }
15
+
16
+ getValue(): DG.DataFrame { return this.grid.dataFrame; }
17
+
18
+ setValue(value: DG.DataFrame): void { this.grid.dataFrame = value; }
19
+
20
+ getStringValue(): string { return this.grid.dataFrame.toCsv(); }
21
+
22
+ setStringValue(str: string): void { this.grid.dataFrame = DG.DataFrame.fromCsv(str); }
23
+
24
+ get placeholdersBreadthValue(): PolyToolPlaceholdersBreadth {
25
+ return dfToPlaceholdersBreadth(this.grid.dataFrame);
26
+ }
27
+
28
+ private readonly gridHost: HTMLDivElement;
29
+ public readonly grid: DG.Grid;
30
+
31
+ private subs: Unsubscribable[] = [];
32
+
33
+ protected constructor(name: string | undefined, grid: DG.Grid, heightRowCount?: number) {
34
+ super();
35
+
36
+ if (name) this.captionLabel.innerText = name;
37
+
38
+ this.gridHost = ui.div([], {
39
+ classes: 'ui-input-editor',
40
+ style: {width: '100%', height: '100%', marginTop: '-8px', marginBottom: '8px', paddingBottom: '4px'},
41
+ });
42
+
43
+ this.grid = grid;
44
+ this.gridHost.append(this.grid.root);
45
+
46
+ if (heightRowCount != null) {
47
+ this.updateGridHeight(heightRowCount + 0.7);
48
+ } else {
49
+ this.updateGridHeight(this.grid.dataFrame.rowCount + 0.6);
50
+ this.subs.push(this.grid.dataFrame.onRowsAdded
51
+ .subscribe(() => { this.updateGridHeight(this.grid.dataFrame.rowCount + 0.6); }));
52
+ }
53
+ this.grid.root.style.width = `100%`;
54
+
55
+ this.subs.push(this.grid.dataFrame.onDataChanged.subscribe(() => {
56
+ this.fireChanged();
57
+ }));
58
+
59
+ this.subs.push(ui.onSizeChanged(this.grid.root).subscribe(() => {
60
+ this.grid.columns.byIndex(3)!.width = this.grid.root.clientWidth - this.grid.horzScroll.root.offsetWidth -
61
+ this.grid.columns.byIndex(0)!.width - this.grid.columns.byIndex(1)!.width - this.grid.columns.byIndex(2)!.width - 10;
62
+ }));
63
+
64
+ this.root.classList.add('ui-input-polytool-pos-grid');
65
+ this.root.append(this.gridHost);
66
+ }
67
+
68
+ detach(): void {
69
+ for (const sub of this.subs) sub.unsubscribe();
70
+ }
71
+
72
+ public static async create(
73
+ name?: string, options?: {}, heightRowCount?: number
74
+ ): Promise<PolyToolPlaceholdersBreadthInput> {
75
+ const df: DG.DataFrame = DG.DataFrame.fromColumns([
76
+ DG.Column.fromType(DG.COLUMN_TYPE.INT, 'Start', 0),
77
+ DG.Column.fromType(DG.COLUMN_TYPE.INT, 'End', 0),
78
+ DG.Column.fromType(DG.COLUMN_TYPE.STRING, 'Monomers', 0),
79
+ ])!;
80
+ const grid = (await df.plot.fromType(DG.VIEWER.GRID, options)) as DG.Grid;
81
+ grid.sort(['Start', 'End']);
82
+ return new PolyToolPlaceholdersBreadthInput(name, grid, heightRowCount);
83
+ }
84
+
85
+ // -- Update view --
86
+
87
+ private updateGridHeight(visibleRowCount: number): void {
88
+ const gridHeight = this.grid.colHeaderHeight + visibleRowCount * this.grid.props.rowHeight + 6 + 2;
89
+ this.grid.root.style.height = `${gridHeight}px`;
90
+ }
91
+
92
+ // -- Handle events --
93
+
94
+ private gridRootOnSizeChanged(): void {
95
+ this.grid.columns.byIndex(3)!.width = this.grid.root.clientWidth - this.grid.horzScroll.root.offsetWidth -
96
+ this.grid.columns.byIndex(0)!.width - this.grid.columns.byIndex(1)!.width - this.grid.columns.byIndex(2)!.width - 10;
97
+ }
98
+ }
99
+
100
+ export function dfToPlaceholdersBreadth(df: DG.DataFrame): PolyToolPlaceholdersBreadth {
101
+ const res: PolyToolPlaceholdersBreadth = [];
102
+ for (let rowI = 0; rowI < df.rowCount; rowI++) {
103
+ const startPos = parseInt(df.get('Start', rowI));
104
+ const endPos = parseInt(df.get('End', rowI));
105
+ if (!isNaN(startPos) && !isNaN(endPos)) {
106
+ const monomerSymbolList = parseMonomerSymbolList(df.get('Monomers', rowI));
107
+ res.push({start: startPos, end: endPos, monomers: monomerSymbolList});
108
+ }
109
+ }
110
+ return res;
111
+ }
@@ -13,23 +13,15 @@ export class PolyToolPlaceholdersInput extends DG.JsInputBase<DG.DataFrame> {
13
13
 
14
14
  getInput(): HTMLElement { return this.gridHost; }
15
15
 
16
- getValue(): DG.DataFrame {
17
- return this.grid.dataFrame;
18
- }
16
+ getValue(): DG.DataFrame { return this.grid.dataFrame; }
19
17
 
20
- setValue(value: DG.DataFrame): void {
21
- this.grid.dataFrame = value;
22
- }
18
+ setValue(value: DG.DataFrame): void { this.grid.dataFrame = value; }
23
19
 
24
- getStringValue(): string {
25
- return this.grid.dataFrame.toCsv();
26
- }
20
+ getStringValue(): string { return this.grid.dataFrame.toCsv(); }
27
21
 
28
- setStringValue(str: string): void {
29
- this.grid.dataFrame = DG.DataFrame.fromCsv(str);
30
- }
22
+ setStringValue(str: string): void { this.grid.dataFrame = DG.DataFrame.fromCsv(str); }
31
23
 
32
- get placeholdersValue() {
24
+ get placeholdersValue(): PolyToolPlaceholders {
33
25
  return dfToPlaceholders(this.grid.dataFrame);
34
26
  }
35
27
 
@@ -80,7 +72,9 @@ export class PolyToolPlaceholdersInput extends DG.JsInputBase<DG.DataFrame> {
80
72
  public static async create(
81
73
  name?: string, options?: {}, heightRowCount?: number
82
74
  ): Promise<PolyToolPlaceholdersInput> {
83
- const df: DG.DataFrame = DG.DataFrame.fromObjects([{Position: '', Monomers: ''}])!;
75
+ const df: DG.DataFrame = DG.DataFrame.fromColumns([
76
+ DG.Column.fromType(DG.COLUMN_TYPE.INT, 'Position', 0),
77
+ DG.Column.fromType(DG.COLUMN_TYPE.STRING, 'Monomers', 0),])!;
84
78
  const grid = (await df.plot.fromType(DG.VIEWER.GRID, options)) as DG.Grid;
85
79
  grid.sort(['Position']);
86
80
  return new PolyToolPlaceholdersInput(name, grid, heightRowCount);
@@ -102,26 +96,25 @@ export class PolyToolPlaceholdersInput extends DG.JsInputBase<DG.DataFrame> {
102
96
  }
103
97
 
104
98
  export function getPlaceholdersFromText(src: string): PolyToolPlaceholders {
105
- const res: PolyToolPlaceholders = {};
99
+ const res: PolyToolPlaceholders = [];
106
100
  for (const line of src.split('\n')) {
107
101
  const lineM = /^\s*(?<pos>\d+)\s*:\s*(?<monomers>.+)$/.exec(line);
108
102
  if (lineM) {
109
103
  const pos: number = parseInt(lineM.groups!['pos']) - 1;
110
- const monomerList: string[] = lineM.groups!['monomers'].split(',').map(m => m.trim());
111
- if (!(pos in res)) res[pos] = [];
112
- res[pos].push(...monomerList);
104
+ const monomerList: string[] = lineM.groups!['monomers'].split(',').map((m) => m.trim());
105
+ res.push({position: pos, monomers: monomerList});
113
106
  }
114
107
  }
115
108
  return res;
116
109
  }
117
110
 
118
111
  export function dfToPlaceholders(df: DG.DataFrame): PolyToolPlaceholders {
119
- const res: PolyToolPlaceholders = {};
112
+ const res: PolyToolPlaceholders = [];
120
113
  for (let rowI = 0; rowI < df.rowCount; rowI++) {
121
114
  const pos = parseInt(df.get('Position', rowI));
122
115
  if (!isNaN(pos)) {
123
116
  const monomerSymbolList = parseMonomerSymbolList(df.get('Monomers', rowI));
124
- res[pos - 1] = monomerSymbolList;
117
+ res.push({position: pos, monomers: monomerSymbolList});
125
118
  }
126
119
  }
127
120
  return res;
@@ -9,12 +9,15 @@ export enum PolyToolEnumeratorTypes {
9
9
 
10
10
  export type PolyToolEnumeratorType = typeof PolyToolEnumeratorTypes[keyof typeof PolyToolEnumeratorTypes];
11
11
 
12
- export type PolyToolPlaceholders = { [position: number]: string[] };
12
+ export type PolyToolPlaceholders = { position: number, monomers: string[] } [];
13
+
14
+ export type PolyToolPlaceholdersBreadth = { start: number, end: number, monomers: string[] }[];
13
15
 
14
16
  export type PolyToolEnumeratorParams = {
15
17
  type: PolyToolEnumeratorType;
16
18
  /** position key is zero-based */
17
- placeholders: PolyToolPlaceholders;
19
+ placeholders?: PolyToolPlaceholders;
20
+ placeholdersBreadth?: PolyToolPlaceholdersBreadth;
18
21
  keepOriginal?: boolean;
19
22
  trivialName?: boolean;
20
23
  }
@@ -0,0 +1,118 @@
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 {before, after, category, expect, test, expectArray} from '@datagrok-libraries/utils/src/test';
6
+ import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
7
+ import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
8
+ import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
9
+ import {
10
+ getUserLibSettings, setUserLibSettings, setUserLibSettingsForTests
11
+ } from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
12
+
13
+ import {PolyToolEnumeratorParams, PolyToolEnumeratorTypes} from '../polytool/types';
14
+ import {doPolyToolEnumerateHelm} from '../polytool/pt-enumeration-helm';
15
+
16
+ import {_package} from '../package-test';
17
+
18
+ category('PolyTool: Enumerate', () => {
19
+ let helmHelper: IHelmHelper;
20
+ let monomerLibHelper: IMonomerLibHelper;
21
+ let userLibSettings: UserLibSettings; //backup
22
+
23
+ before(async () => {
24
+ helmHelper = await getHelmHelper(); // initialize JSDraw2 and org
25
+
26
+ monomerLibHelper = await getMonomerLibHelper();
27
+ userLibSettings = await getUserLibSettings();
28
+ // Clear settings to test default
29
+ await setUserLibSettingsForTests();
30
+ await monomerLibHelper.awaitLoaded();
31
+ await monomerLibHelper.loadMonomerLib(true);
32
+ });
33
+
34
+ after(async () => {
35
+ await setUserLibSettings(userLibSettings);
36
+ await monomerLibHelper.loadMonomerLib(true);
37
+ });
38
+
39
+ const tests: {
40
+ [testName: string]: { src: string, params: PolyToolEnumeratorParams, tgt: { seq: string, name: string }[] }
41
+ } = {
42
+ 'breadth1': {
43
+ src: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0',
44
+ params: {
45
+ type: PolyToolEnumeratorTypes.Single,
46
+ placeholdersBreadth: [
47
+ {start: 2, end: 4, monomers: ['K']},
48
+ ],
49
+ },
50
+ tgt: [
51
+ {seq: 'PEPTIDE1{[Ac(1)].F.K.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-W3K'},
52
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.K.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-G4K'},
53
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.K.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-P5K'},
54
+ ],
55
+ },
56
+ 'breadth1-with-original': {
57
+ src: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0',
58
+ params: {
59
+ type: PolyToolEnumeratorTypes.Single,
60
+ placeholdersBreadth: [
61
+ {start: 2, end: 4, monomers: ['K']},
62
+ ],
63
+ keepOriginal: true,
64
+ },
65
+ tgt: [
66
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: ''},
67
+ {seq: 'PEPTIDE1{[Ac(1)].F.K.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-W3K'},
68
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.K.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-G4K'},
69
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.K.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-P5K'},
70
+ ],
71
+ },
72
+ 'breadth2': {
73
+ src: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0',
74
+ params: {
75
+ type: PolyToolEnumeratorTypes.Single,
76
+ placeholdersBreadth: [
77
+ {start: 2, end: 4, monomers: ['K', 'Y']},
78
+ ],
79
+ },
80
+ tgt: [
81
+ {seq: 'PEPTIDE1{[Ac(1)].F.K.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-W3K'},
82
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.K.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-G4K'},
83
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.K.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-P5K'},
84
+ {seq: 'PEPTIDE1{[Ac(1)].F.Y.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-W3Y'},
85
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.Y.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-G4Y'},
86
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.Y.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-P5Y'},
87
+ ],
88
+ },
89
+ 'breadth-double': {
90
+ src: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0',
91
+ params: {
92
+ type: PolyToolEnumeratorTypes.Single,
93
+ placeholdersBreadth: [
94
+ {start: 2, end: 4, monomers: ['K']},
95
+ {start: 2, end: 4, monomers: ['Y']},
96
+ ],
97
+ },
98
+ tgt: [
99
+ {seq: "PEPTIDE1{[Ac(1)].F.Y.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0", name: "-W3K-K3Y"},
100
+ {seq: "PEPTIDE1{[Ac(1)].F.K.Y.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0", name: "-W3K-G4Y"},
101
+ {seq: "PEPTIDE1{[Ac(1)].F.K.G.Y.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0", name: "-W3K-P5Y"},
102
+ {seq: "PEPTIDE1{[Ac(1)].F.Y.K.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0", name: "-G4K-W3Y"},
103
+ {seq: "PEPTIDE1{[Ac(1)].F.W.Y.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0", name: "-G4K-K4Y"},
104
+ {seq: "PEPTIDE1{[Ac(1)].F.W.K.Y.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0", name: "-G4K-P5Y"},
105
+ {seq: "PEPTIDE1{[Ac(1)].F.Y.G.K.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0", name: "-P5K-W3Y"},
106
+ {seq: "PEPTIDE1{[Ac(1)].F.W.Y.K.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0", name: "-P5K-G4Y"},
107
+ {seq: "PEPTIDE1{[Ac(1)].F.W.G.Y.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0", name: "-P5K-K5Y"}
108
+ ]
109
+ }
110
+ };
111
+
112
+ for (const [testName, testData] of Object.entries(tests)) {
113
+ test(`${testName}`, async () => {
114
+ const res = doPolyToolEnumerateHelm(testData.src, '', testData.params);
115
+ expectArray(res, testData.tgt.map((r) => [r.seq, r.name]));
116
+ });
117
+ }
118
+ });
@@ -27,6 +27,7 @@ category('PolyTool: Enumerate', () => {
27
27
  userLibSettings = await getUserLibSettings();
28
28
  // Clear settings to test default
29
29
  await setUserLibSettingsForTests();
30
+ await monomerLibHelper.awaitLoaded();
30
31
  await monomerLibHelper.loadMonomerLib(true);
31
32
  });
32
33
 
@@ -36,42 +37,42 @@ category('PolyTool: Enumerate', () => {
36
37
  });
37
38
 
38
39
  const tests: {
39
- [testName: string]: { src: string, params: PolyToolEnumeratorParams, tgt: [string, string][] }
40
+ [testName: string]: { src: string, params: PolyToolEnumeratorParams, tgt: { seq: string, name: string }[] }
40
41
  } = {
41
42
  'single1': {
42
43
  src: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0',
43
44
  params: {
44
45
  type: PolyToolEnumeratorTypes.Single,
45
- placeholders: {
46
- [4]: ['K', 'P', 'F4COO'],
47
- [6]: ['Y', 'T'],
48
- },
46
+ placeholders: [
47
+ {position: 4, monomers: ['K', 'P', 'F4COO']},
48
+ {position: 6, monomers: ['Y', 'T']},
49
+ ],
49
50
  },
50
51
  tgt: [
51
- ['PEPTIDE1{[Ac(1)].F.W.G.K.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', '-P5K'],
52
- ['PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', '-P5P'],
53
- ['PEPTIDE1{[Ac(1)].F.W.G.[F4COO].L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', '-P5[F4COO]'],
54
- ['PEPTIDE1{[Ac(1)].F.W.G.P.L.Y.[C(1)].G.[NH2]}$$$$V2.0', '-[Tic]7Y'],
55
- ['PEPTIDE1{[Ac(1)].F.W.G.P.L.T.[C(1)].G.[NH2]}$$$$V2.0', '-[Tic]7T'],
52
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.K.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-P5K'},
53
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-P5P'},
54
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.[F4COO].L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-P5[F4COO]'},
55
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.Y.[C(1)].G.[NH2]}$$$$V2.0', name: '-[Tic]7Y'},
56
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.T.[C(1)].G.[NH2]}$$$$V2.0', name: '-[Tic]7T'},
56
57
  ]
57
58
  },
58
59
  'single-with-original': {
59
60
  src: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0',
60
61
  params: {
61
62
  type: PolyToolEnumeratorTypes.Single,
62
- placeholders: {
63
- [4]: ['K', 'P', 'F4COO'],
64
- [6]: ['Y', 'T'],
65
- },
63
+ placeholders: [
64
+ {position: 4, monomers: ['K', 'P', 'F4COO']},
65
+ {position: 6, monomers: ['Y', 'T']},
66
+ ],
66
67
  keepOriginal: true,
67
68
  },
68
69
  tgt: [
69
- ['PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', ''],
70
- ['PEPTIDE1{[Ac(1)].F.W.G.K.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', '-P5K'],
71
- ['PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', '-P5P'],
72
- ['PEPTIDE1{[Ac(1)].F.W.G.[F4COO].L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', '-P5[F4COO]'],
73
- ['PEPTIDE1{[Ac(1)].F.W.G.P.L.Y.[C(1)].G.[NH2]}$$$$V2.0', '-[Tic]7Y'],
74
- ['PEPTIDE1{[Ac(1)].F.W.G.P.L.T.[C(1)].G.[NH2]}$$$$V2.0', '-[Tic]7T'],
70
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: ''},
71
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.K.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-P5K'},
72
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-P5P'},
73
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.[F4COO].L.[Tic].[C(1)].G.[NH2]}$$$$V2.0', name: '-P5[F4COO]'},
74
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.Y.[C(1)].G.[NH2]}$$$$V2.0', name: '-[Tic]7Y'},
75
+ {seq: 'PEPTIDE1{[Ac(1)].F.W.G.P.L.T.[C(1)].G.[NH2]}$$$$V2.0', name: '-[Tic]7T'},
75
76
  ]
76
77
  },
77
78
  'matrix1': {
@@ -79,25 +80,25 @@ category('PolyTool: Enumerate', () => {
79
80
  params:
80
81
  {
81
82
  type: PolyToolEnumeratorTypes.Matrix,
82
- placeholders: {
83
- [1]: ['D', 'L'],
84
- [4]: ['K', 'P', 'F4COO'],
85
- [6]: ['Y', 'T'],
86
- }
83
+ placeholders: [
84
+ {position: 1, monomers: ['D', 'L']},
85
+ {position: 4, monomers: ['K', 'P', 'F4COO']},
86
+ {position: 6, monomers: ['Y', 'T']},
87
+ ]
87
88
  },
88
89
  tgt: [
89
- ["PEPTIDE1{[Ac(1)].D.W.G.K.L.Y.[C(1)].G.[NH2]}$$$$V2.0", "-F2D-P5K-[Tic]7Y"],
90
- ["PEPTIDE1{[Ac(1)].D.W.G.K.L.T.[C(1)].G.[NH2]}$$$$V2.0", "-F2D-P5K-[Tic]7T"],
91
- ["PEPTIDE1{[Ac(1)].D.W.G.P.L.Y.[C(1)].G.[NH2]}$$$$V2.0", "-F2D-P5P-[Tic]7Y"],
92
- ["PEPTIDE1{[Ac(1)].D.W.G.P.L.T.[C(1)].G.[NH2]}$$$$V2.0", "-F2D-P5P-[Tic]7T"],
93
- ["PEPTIDE1{[Ac(1)].D.W.G.[F4COO].L.Y.[C(1)].G.[NH2]}$$$$V2.0", "-F2D-P5[F4COO]-[Tic]7Y"],
94
- ["PEPTIDE1{[Ac(1)].D.W.G.[F4COO].L.T.[C(1)].G.[NH2]}$$$$V2.0", "-F2D-P5[F4COO]-[Tic]7T"],
95
- ["PEPTIDE1{[Ac(1)].L.W.G.K.L.Y.[C(1)].G.[NH2]}$$$$V2.0", "-F2L-P5K-[Tic]7Y"],
96
- ["PEPTIDE1{[Ac(1)].L.W.G.K.L.T.[C(1)].G.[NH2]}$$$$V2.0", "-F2L-P5K-[Tic]7T"],
97
- ["PEPTIDE1{[Ac(1)].L.W.G.P.L.Y.[C(1)].G.[NH2]}$$$$V2.0", "-F2L-P5P-[Tic]7Y"],
98
- ["PEPTIDE1{[Ac(1)].L.W.G.P.L.T.[C(1)].G.[NH2]}$$$$V2.0", "-F2L-P5P-[Tic]7T"],
99
- ["PEPTIDE1{[Ac(1)].L.W.G.[F4COO].L.Y.[C(1)].G.[NH2]}$$$$V2.0", "-F2L-P5[F4COO]-[Tic]7Y"],
100
- ["PEPTIDE1{[Ac(1)].L.W.G.[F4COO].L.T.[C(1)].G.[NH2]}$$$$V2.0", "-F2L-P5[F4COO]-[Tic]7T"],
90
+ {seq: 'PEPTIDE1{[Ac(1)].D.W.G.K.L.Y.[C(1)].G.[NH2]}$$$$V2.0', name: '-F2D-P5K-[Tic]7Y'},
91
+ {seq: 'PEPTIDE1{[Ac(1)].D.W.G.K.L.T.[C(1)].G.[NH2]}$$$$V2.0', name: '-F2D-P5K-[Tic]7T'},
92
+ {seq: 'PEPTIDE1{[Ac(1)].D.W.G.P.L.Y.[C(1)].G.[NH2]}$$$$V2.0', name: '-F2D-P5P-[Tic]7Y'},
93
+ {seq: 'PEPTIDE1{[Ac(1)].D.W.G.P.L.T.[C(1)].G.[NH2]}$$$$V2.0', name: '-F2D-P5P-[Tic]7T'},
94
+ {seq: 'PEPTIDE1{[Ac(1)].D.W.G.[F4COO].L.Y.[C(1)].G.[NH2]}$$$$V2.0', name: '-F2D-P5[F4COO]-[Tic]7Y'},
95
+ {seq: 'PEPTIDE1{[Ac(1)].D.W.G.[F4COO].L.T.[C(1)].G.[NH2]}$$$$V2.0', name: '-F2D-P5[F4COO]-[Tic]7T'},
96
+ {seq: 'PEPTIDE1{[Ac(1)].L.W.G.K.L.Y.[C(1)].G.[NH2]}$$$$V2.0', name: '-F2L-P5K-[Tic]7Y'},
97
+ {seq: 'PEPTIDE1{[Ac(1)].L.W.G.K.L.T.[C(1)].G.[NH2]}$$$$V2.0', name: '-F2L-P5K-[Tic]7T'},
98
+ {seq: 'PEPTIDE1{[Ac(1)].L.W.G.P.L.Y.[C(1)].G.[NH2]}$$$$V2.0', name: '-F2L-P5P-[Tic]7Y'},
99
+ {seq: 'PEPTIDE1{[Ac(1)].L.W.G.P.L.T.[C(1)].G.[NH2]}$$$$V2.0', name: '-F2L-P5P-[Tic]7T'},
100
+ {seq: 'PEPTIDE1{[Ac(1)].L.W.G.[F4COO].L.Y.[C(1)].G.[NH2]}$$$$V2.0', name: '-F2L-P5[F4COO]-[Tic]7Y'},
101
+ {seq: 'PEPTIDE1{[Ac(1)].L.W.G.[F4COO].L.T.[C(1)].G.[NH2]}$$$$V2.0', name: '-F2L-P5[F4COO]-[Tic]7T'},
101
102
  ],
102
103
  }
103
104
  };
@@ -105,7 +106,7 @@ category('PolyTool: Enumerate', () => {
105
106
  for (const [testName, testData] of Object.entries(tests)) {
106
107
  test(`${testName}`, async () => {
107
108
  const res = doPolyToolEnumerateHelm(testData.src, '', testData.params);
108
- expectArray(res, testData.tgt);
109
+ expectArray(res, testData.tgt.map((r) => [r.seq, r.name]));
109
110
  });
110
111
  }
111
112
  });