@datagrok/bio 2.8.6 → 2.10.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.
@@ -17,64 +17,93 @@ export const enum MONOMERIC_COL_TAGS {
17
17
 
18
18
  const SUBSTR_HELM_COL_NAME = 'substr_helm';
19
19
 
20
- /**
21
- * Searches substructure in each row of Macromolecule column
22
- *
23
- * @param {DG.column} col Column with 'Macromolecule' semantic type
24
- */
25
- export function substructureSearchDialog(col: DG.Column<string>): void {
26
- const units = col.getTag(DG.TAGS.UNITS);
27
- const separator = col.getTag(bioTAGS.separator);
28
- // const notations = [NOTATION.FASTA, NOTATION.SEPARATOR, NOTATION.HELM];
29
-
30
- const substructureInput = ui.textInput('Substructure', '');
31
-
32
- const editHelmLink = ui.link('Edit helm', async () => {
33
- updateDivInnerHTML(inputsDiv, grid.root);
34
- await ui.tools.waitForElementInDom(grid.root);
35
- setTimeout(() => {
36
- grid.cell(SUBSTR_HELM_COL_NAME, 0).element.children[0].dispatchEvent(
37
- new KeyboardEvent('keydown', {key: 'Enter'}));
38
- }, 100);
39
- });
20
+ export class SubstructureSearchDialog {
21
+ units: string;
22
+ separator: string;
23
+ inputsDiv: HTMLDivElement;
24
+ substructureInput: DG.InputBase<string>;
25
+ separatorInput: DG.InputBase<string>;
26
+ editHelmLink: HTMLAnchorElement;
27
+ columnsInput: DG.InputBase<DG.Column | null>;
28
+ grid: DG.Grid;
29
+ col: DG.Column;
30
+ dialog: DG.Dialog;
31
+
32
+ constructor(columns: DG.Column<string>[]) {
33
+ this.col = columns[0];
34
+ this.createUI();
35
+ }
36
+
37
+ editHelmLinkAction(): void {
38
+ updateDivInnerHTML(this.inputsDiv, this.grid.root);
39
+ ui.tools.waitForElementInDom(this.grid.root).then(() => {
40
+ setTimeout(() => {
41
+ this.grid.cell(SUBSTR_HELM_COL_NAME, 0).element.children[0].dispatchEvent(
42
+ new KeyboardEvent('keydown', {key: 'Enter'})
43
+ );
44
+ }, 100);
45
+ });
46
+ }
47
+
48
+ updateInputs(): void {
49
+ const selectedInput = this.units === NOTATION.HELM ? ui.divV([this.columnsInput, this.editHelmLink]) :
50
+ this.units === NOTATION.SEPARATOR ? ui.inputs([this.columnsInput, this.substructureInput, this.separatorInput]) :
51
+ ui.inputs([this.columnsInput, this.substructureInput]);
40
52
 
41
- const df = DG.DataFrame.create(1);
42
- df.columns.addNewString(SUBSTR_HELM_COL_NAME).init((_i) => '');
43
- df.col(SUBSTR_HELM_COL_NAME)!.semType = col.semType;
44
- df.col(SUBSTR_HELM_COL_NAME)!.setTag(DG.TAGS.UNITS, NOTATION.HELM);
45
- const grid = df.plot.grid();
46
- const separatorInput = ui.textInput('Separator', separator);
47
-
48
- const inputsDiv = ui.div();
49
-
50
- const inputs = units === NOTATION.HELM ? ui.divV([editHelmLink]) :
51
- units === NOTATION.SEPARATOR ? ui.inputs([substructureInput, separatorInput]) :
52
- ui.inputs([substructureInput]);
53
-
54
- updateDivInnerHTML(inputsDiv, inputs);
55
-
56
- ui.dialog('Substructure Search')
57
- .add(ui.divV([
58
- ui.divText(`Notation: ${units}`),
59
- inputsDiv,
60
- ]))
61
- .onOK(async () => {
62
- let substructure = units === NOTATION.HELM ? df.get(SUBSTR_HELM_COL_NAME, 0) : substructureInput.value;
63
- if (units === NOTATION.SEPARATOR && separatorInput.value !== separator && separatorInput.value !== '')
64
- substructure = substructure.replaceAll(separatorInput.value, separator);
65
- const matchesColName = `Matches: ${substructure}`;
66
- const colExists = col.dataFrame.columns.names()
67
- .filter((it) => it.toLocaleLowerCase() === matchesColName.toLocaleLowerCase()).length > 0;
68
- if (!colExists) {
53
+ updateDivInnerHTML(this.inputsDiv, selectedInput);
54
+ }
55
+
56
+ updateNotationDiv(): void {
57
+ this.units = this.col.getTag(DG.TAGS.UNITS);
58
+ this.separator = this.col.getTag(bioTAGS.separator);
59
+ const notationDiv = this.dialog.root.getElementsByClassName('notation-text')[0];
60
+ if (notationDiv)
61
+ notationDiv.textContent = `Notation: ${this.units}`;
62
+ }
63
+
64
+ createUI(): void {
65
+ const dataframe = grok.shell.tv.dataFrame;
66
+ const seqColOptions = {filter: (col: DG.Column) => col.semType === DG.SEMTYPE.MACROMOLECULE};
67
+ this.columnsInput = ui.columnInput('Column', dataframe, this.col, (column: DG.Column) => {
68
+ this.col = column;
69
+ this.updateNotationDiv();
70
+ this.updateInputs();
71
+ }, seqColOptions);
72
+
73
+ this.substructureInput = ui.stringInput('Substructure', '');
74
+
75
+ this.editHelmLink = ui.link('Edit helm', () => this.editHelmLinkAction(), undefined, {style: {position: 'relative', left: '95px'}});
76
+
77
+ const df = DG.DataFrame.create(1);
78
+ df.columns.addNewString(SUBSTR_HELM_COL_NAME).init((_i) => '');
79
+ df.col(SUBSTR_HELM_COL_NAME)!.semType = this.col.semType;
80
+ df.col(SUBSTR_HELM_COL_NAME)!.setTag(DG.TAGS.UNITS, NOTATION.HELM);
81
+ this.grid = df.plot.grid();
82
+ this.separatorInput = ui.stringInput('Separator', this.separator);
83
+
84
+ this.inputsDiv = ui.div();
85
+ this.units = this.col.getTag(DG.TAGS.UNITS);
86
+ this.separator = this.col.getTag(bioTAGS.separator);
87
+ this.updateInputs();
88
+
89
+ this.dialog = ui.dialog('Substructure Search')
90
+ .add(ui.divV([
91
+ ui.divText(`Notation: ${this.units}`, 'notation-text'),
92
+ this.inputsDiv,
93
+ ]))
94
+ .onOK(async () => {
95
+ let substructure = this.units === NOTATION.HELM ? df.get(SUBSTR_HELM_COL_NAME, 0) : this.substructureInput.value;
96
+ if (this.units === NOTATION.SEPARATOR && this.separatorInput.value !== this.separator && this.separatorInput.value !== '')
97
+ substructure = substructure.replaceAll(this.separatorInput.value, this.separator);
69
98
  let matches: DG.BitSet;
70
- if (units === NOTATION.HELM)
71
- matches = await helmSubstructureSearch(substructure, col);
99
+ if (this.units === NOTATION.HELM)
100
+ matches = await helmSubstructureSearch(substructure, this.col);
72
101
  else
73
- matches = linearSubstructureSearch(substructure, col);
74
- col.dataFrame.columns.add(DG.Column.fromBitSet(matchesColName, matches));
75
- } else { grok.shell.warning(`Search ${substructure} is already performed`); }
76
- })
77
- .show();
102
+ matches = linearSubstructureSearch(substructure, this.col);
103
+ this.col.dataFrame.filter.and(matches);
104
+ })
105
+ .show();
106
+ }
78
107
  }
79
108
 
80
109
  export function linearSubstructureSearch(substructure: string, col: DG.Column<string>, separator?: string): DG.BitSet {
@@ -47,5 +47,5 @@ category('activityCliffs', async () => {
47
47
  viewList.push(actCliffsTableViewWithEmptyRows);
48
48
 
49
49
  await _testActivityCliffsOpen(actCliffsDfWithEmptyRows, 3, DimReductionMethods.UMAP, 'sequence');
50
- });
50
+ }, {skipReason: 'GROK-13851: Unhandled exceptions'});
51
51
  });
@@ -5,7 +5,6 @@ import {category, expect, expectArray, test} from '@datagrok-libraries/utils/src
5
5
 
6
6
  import {ConverterFunc} from './types';
7
7
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
8
- import {NotationConverter} from '@datagrok-libraries/bio/src/utils/notation-converter';
9
8
  import {UnitsHandler} from '@datagrok-libraries/bio/src/utils/units-handler';
10
9
 
11
10
  // import {mmSemType} from '../const';
@@ -134,8 +133,8 @@ RNA1{P.R(U)P.R(U)P.R(C)P.R(A)P.R(A)P.R(C)P.P.P}$$$$`,
134
133
  throw new Error(`Argument 'separator' is mandatory for target notation '${tgtNotation.toString()}'.`);
135
134
 
136
135
  return function(srcCol: DG.Column): DG.Column {
137
- const converter = new NotationConverter(srcCol);
138
- const resCol = converter.convert(tgtNotation, tgtSeparator);
136
+ const converterUH = UnitsHandler.getOrCreate(srcCol);
137
+ const resCol = converterUH.convert(tgtNotation, tgtSeparator);
139
138
  expect(resCol.getTag(DG.TAGS.UNITS), tgtNotation);
140
139
  return resCol;
141
140
  };
@@ -274,13 +274,13 @@ MWRSWY-CKHP`;
274
274
  await _testDf(readSamples(Samples.fastaCsv), {
275
275
  'Sequence': new PosCol(NOTATION.FASTA, ALIGNMENT.SEQ, ALPHABET.PT, 20, false),
276
276
  });
277
- });
277
+ }, {skipReason: 'GROK-13851: Unhandled exceptions'});
278
278
 
279
279
  test('samplesFastaFasta', async () => {
280
280
  await _testDf(readSamples(Samples.fastaFasta), {
281
281
  'sequence': new PosCol(NOTATION.FASTA, ALIGNMENT.SEQ, ALPHABET.PT, 20, false),
282
282
  });
283
- });
283
+ }, {skipReason: 'GROK-13851: Unhandled exceptions'});
284
284
 
285
285
  // peptidesComplex contains monomers with spaces in AlignedSequence columns, which are forbidden
286
286
  // test('samplesPeptidesComplexPositiveAlignedSequence', async () => {
@@ -0,0 +1,42 @@
1
+ import * as DG from 'datagrok-api/dg';
2
+
3
+ import {category, test, expectFloat, before} from '@datagrok-libraries/utils/src/test';
4
+ import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
5
+ import {sequenceIdentityScoring, sequenceSimilarityScoring} from '../package';
6
+ import {getMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
7
+
8
+ category('Scoring', () => {
9
+ const sequence = 'sequence';
10
+ const expectedSimilarity = 'expected_similarity';
11
+ const expectedIdentity = 'expected_identity';
12
+ const table = DG.DataFrame.fromCsv(`${sequence},${expectedSimilarity},${expectedIdentity}
13
+ PEPTIDE1{Aca.Orn.gGlu.Pqa.D-His_1Bn.dH.hHis.4Abz.D-Tic.D-Dap.Y.Iva.meS.F.P.F.D-1Nal}$$$$,1.0,1.0
14
+ PEPTIDE1{Iva.Gly_allyl.gGlu.Pqa.D-Dip.dH.hHis.4Abz.D-aHyp.D-Dap.Y.Iva.I.Tyr_26diMe.P.Asu.meC}$$$$,0.68,0.53
15
+ PEPTIDE1{[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal].[1Nal]}$$$$V2.0,0.34,0.0
16
+ `);
17
+ const seqCol: DG.Column<string> = table.getCol(sequence);
18
+ seqCol.setTag(DG.TAGS.UNITS, NOTATION.HELM);
19
+ seqCol.semType = DG.SEMTYPE.MACROMOLECULE;
20
+ const reference = seqCol.get(0)!;
21
+
22
+ before(async () => {
23
+ const monomerLibHelper = await getMonomerLibHelper();
24
+ await monomerLibHelper.loadLibraries(true);
25
+ });
26
+
27
+ test('Identity', async () => {
28
+ const scoresCol = await sequenceIdentityScoring(table, seqCol, reference);
29
+ for (let i = 0; i < scoresCol.length; i++) {
30
+ expectFloat(scoresCol.get(i)!, table.get(expectedIdentity, i), 0.01,
31
+ `Wrong identity score for sequence at position ${i}`);
32
+ }
33
+ });
34
+
35
+ test('Similarity', async () => {
36
+ const scoresCol = await sequenceSimilarityScoring(table, seqCol, reference);
37
+ for (let i = 0; i < scoresCol.length; i++) {
38
+ expectFloat(scoresCol.get(i)!, table.get(expectedSimilarity, i), 0.01,
39
+ `Wrong similarity score for sequence at position ${i}`);
40
+ }
41
+ });
42
+ });
@@ -0,0 +1,116 @@
1
+ import * as grok from 'datagrok-api/grok';
2
+ import * as DG from 'datagrok-api/dg';
3
+
4
+ import {category, expect, expectArray, test} from '@datagrok-libraries/utils/src/test';
5
+ import {UnitsHandler} from '@datagrok-libraries/bio/src/utils/units-handler';
6
+ import {ALPHABET, NOTATION, TAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
7
+
8
+ category('UnitsHandler: getRegion', () => {
9
+ const data: {
10
+ [testName: string]: {
11
+ srcCsv: string,
12
+ startIdx: number | null,
13
+ endIdx: number | null,
14
+ tgtCsv: string,
15
+ units: NOTATION,
16
+ alphabet: ALPHABET | null, /* alphabet is not applicable for units 'helm' */
17
+
18
+ positionNames?: { tag: string | null, start: string | null, end: string | null }
19
+ }
20
+ } = {
21
+ 'fastaDna': {
22
+ srcCsv: `seq
23
+ ATTCGT
24
+ ACTGCTC
25
+ ATTCCGTA`,
26
+ startIdx: 2,
27
+ endIdx: 4,
28
+ tgtCsv: `seq
29
+ TCG
30
+ TGC
31
+ TCC`,
32
+ units: NOTATION.FASTA,
33
+ alphabet: ALPHABET.DNA,
34
+
35
+ positionNames: {tag: 'a, b, c, d, e, f, g, h', start: 'c', end: 'e'},
36
+ },
37
+ 'separatorPt': {
38
+ srcCsv: `seq
39
+ M-D-Y-K-E-T-L
40
+ M-I-E-V-F-L-F-G-I
41
+ M-M-`,
42
+ startIdx: 5,
43
+ endIdx: null,
44
+ tgtCsv: `seq
45
+ T-L--
46
+ L-F-G-I
47
+ ---`,
48
+ units: NOTATION.SEPARATOR,
49
+ alphabet: ALPHABET.PT,
50
+
51
+ positionNames: {tag: '1, 1A, 1B, 2, 3, 4, 4A, 4A, 4C', start: '4', end: null},
52
+ },
53
+ 'helm': {
54
+ srcCsv: `seq
55
+ PEPTIDE1{[meI].[hHis].[Aca].N.T.[dE].[Thr_PO3H2].[Aca].[D-Tyr_Et].[Tyr_ab-dehydroMe].[dV].E.N.[D-Orn]}$$$$
56
+ PEPTIDE1{[meI].[hHis].[Aca].[Cys_SEt].T.[dK].[Thr_PO3H2].[Aca].[Tyr_PO3H2].[D-Chg].[dV].[Phe_ab-dehydro]}$$$$
57
+ PEPTIDE1{[Lys_Boc].[hHis].[Aca].[Cys_SEt].T}$$$$`,
58
+ startIdx: 3,
59
+ endIdx: 6,
60
+ tgtCsv: `seq
61
+ PEPTIDE1{N.T.[dE].[Thr_PO3H2]}$$$$
62
+ PEPTIDE1{[Cys_SEt].T.[dK].[Thr_PO3H2]}$$$$
63
+ PEPTIDE1{[Cys_SEt].T.*.*}$$$$`,
64
+ units: NOTATION.HELM,
65
+ alphabet: null,
66
+
67
+ positionNames: {tag: null, start: '4', end: '7'}
68
+ }
69
+ };
70
+
71
+ for (const [testName, testData] of Object.entries(data)) {
72
+ test(`${testName}-idx`, async () => {
73
+ const srcDf = DG.DataFrame.fromCsv(testData.srcCsv);
74
+ const srcSeqCol = srcDf.getCol('seq');
75
+
76
+ const semType: string | null = await grok.functions.call('Bio:detectMacromolecule', {col: srcSeqCol});
77
+ if (semType) srcSeqCol.semType = semType;
78
+
79
+ const srcUh = UnitsHandler.getOrCreate(srcSeqCol);
80
+ const resSeqCol = srcUh.getRegion(testData.startIdx, testData.endIdx, 'regSeq');
81
+
82
+ const tgtDf = DG.DataFrame.fromCsv(testData.tgtCsv);
83
+ const tgtSeqCol = tgtDf.getCol('seq');
84
+
85
+ expect(srcSeqCol.getTag(DG.TAGS.UNITS), testData.units);
86
+ expect(resSeqCol.getTag(DG.TAGS.UNITS), testData.units);
87
+ expect(srcSeqCol.getTag(TAGS.alphabet), testData.alphabet);
88
+ expect(resSeqCol.getTag(TAGS.alphabet), testData.alphabet);
89
+ expectArray(resSeqCol.toList(), tgtSeqCol.toList());
90
+ });
91
+
92
+ if (testData.positionNames) {
93
+ test(`${testName}-positionNames`, async () => {
94
+ const srcDf = DG.DataFrame.fromCsv(testData.srcCsv);
95
+ const srcSeqCol = srcDf.getCol('seq');
96
+ if (testData.positionNames!.tag)
97
+ srcSeqCol.setTag(TAGS.positionNames, testData.positionNames!.tag);
98
+
99
+ const semType: string | null = await grok.functions.call('Bio:detectMacromolecule', {col: srcSeqCol});
100
+ if (semType) srcSeqCol.semType = semType;
101
+
102
+ const resSeqCol = await grok.functions.call('Bio:getRegion',
103
+ {sequence: srcSeqCol, start: testData.positionNames!.start, end: testData.positionNames!.end});
104
+
105
+ const tgtDf = DG.DataFrame.fromCsv(testData.tgtCsv);
106
+ const tgtSeqCol = tgtDf.getCol('seq');
107
+
108
+ expect(srcSeqCol.getTag(DG.TAGS.UNITS), testData.units);
109
+ expect(resSeqCol.getTag(DG.TAGS.UNITS), testData.units);
110
+ expect(srcSeqCol.getTag(TAGS.alphabet), testData.alphabet);
111
+ expect(resSeqCol.getTag(TAGS.alphabet), testData.alphabet);
112
+ expectArray(resSeqCol.toList(), tgtSeqCol.toList());
113
+ });
114
+ }
115
+ }
116
+ });
@@ -26,6 +26,7 @@ import * as C from './constants';
26
26
 
27
27
  import {_package, getBioLib} from '../package';
28
28
  import {ISeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
29
+ import {getSplitter} from '@datagrok-libraries/bio/src/utils/macromolecule/utils';
29
30
 
30
31
 
31
32
  type TempType = { [tagName: string]: any };
@@ -142,8 +143,11 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
142
143
  // Cell renderer settings
143
144
  const tempMonomerWidth: string | null = tableColTemp[tempTAGS.monomerWidth];
144
145
  const monomerWidth: string = (tempMonomerWidth != null) ? tempMonomerWidth : 'short';
145
- if (monomerWidth === 'short')
146
- maxLengthOfMonomer = tableColTemp[mmcrTemps.maxMonomerLength] ?? _package.properties.MaxMonomerLength;
146
+ if (monomerWidth === 'short') {
147
+ // Renderer can start to work before Bio package initialized, in that time _package.properties is null.
148
+ // TODO: Render function is available but package init method is not completed
149
+ maxLengthOfMonomer = tableColTemp[mmcrTemps.maxMonomerLength] ?? _package.properties?.MaxMonomerLength ?? 4;
150
+ }
147
151
 
148
152
 
149
153
  let seqColTemp: MonomerPlacer = tableCol.temp[tempTAGS.bioSeqCol];
@@ -205,36 +209,6 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
205
209
  ((tempReferenceSequence != null) && (tempReferenceSequence != '')) ?
206
210
  tempReferenceSequence : tempCurrentWord ?? '');
207
211
 
208
- // let maxLengthWords: { [pos: number]: number } = {};
209
- // if (tableCol.getTag(rndrTAGS.calculatedCellRender) !== splitLimit.toString()) {
210
- // let sampleCount = 0;
211
- // while (sampleCount < Math.min(tableCol.length, 100)) {
212
- // const rowIdx: number = sampleCount;
213
- // const column = tableCol.get(rowIdx);
214
- // const subParts: string[] = splitterFunc(column);
215
- // for (const [index, amino] of subParts.entries()) {
216
- // const textSize = monomerToShortFunction(amino, maxLengthOfMonomer).length * 7 + gapRenderer;
217
- // if (textSize > (maxLengthWords[index] ?? 0))
218
- // maxLengthWords[index] = textSize;
219
- // if (index > maxIndex) maxIndex = index;
220
- // }
221
- // sampleCount += 1;
222
- // }
223
- // const minLength = 3 * 7;
224
- // for (let i = 0; i <= maxIndex; i++) {
225
- // if (maxLengthWords[i] < minLength) maxLengthWords[i] = minLength;
226
- // const maxLengthWordSum: { [pos: number]: number } = {};
227
- // maxLengthWordSum[0] = maxLengthWords[0];
228
- // for (let i = 1; i <= maxIndex; i++) maxLengthWordSum[i] = maxLengthWordSum[i - 1] + maxLengthWords[i];
229
- // colTemp[tempTAGS.bioSumMaxLengthWords] = maxLengthWordSum;
230
- // colTemp[tempTAGS.bioMaxIndex] = maxIndex;
231
- // colTemp[tempTAGS.bioMaxLengthWords] = maxLengthWords;
232
- // tableCol.setTag(rndrTAGS.calculatedCellRender, splitLimit.toString());
233
- // }
234
- // } else {
235
- // maxLengthWords = colTemp[tempTAGS.bioMaxLengthWords];
236
- // }
237
-
238
212
  const subParts: ISeqSplitted = splitterFunc(value);
239
213
  /* let x1 = x; */
240
214
  let color = undefinedColor;
@@ -292,14 +266,15 @@ export class MacromoleculeDifferenceCellRenderer extends DG.GridCellRenderer {
292
266
  const cell = gridCell.cell;
293
267
  const tableCol = gridCell.tableColumn as DG.Column<string>;
294
268
  const s: string = cell.value ?? '';
269
+ const separator = tableCol.tags[bioTAGS.separator];
270
+ const units: string = tableCol.tags[DG.TAGS.UNITS];
295
271
  w = getUpdatedWidth(grid, g, x, w);
296
272
  //TODO: can this be replaced/merged with splitSequence?
297
273
  const [s1, s2] = s.split('#');
298
- const uh = UnitsHandler.getOrCreate(tableCol);
299
- const splitter = uh.getSplitter();
274
+ const splitter = getSplitter(units, separator);
300
275
  const subParts1 = splitter(s1);
301
276
  const subParts2 = splitter(s2);
302
- drawMoleculeDifferenceOnCanvas(g, x, y, w, h, subParts1, subParts2, uh.units);
277
+ drawMoleculeDifferenceOnCanvas(g, x, y, w, h, subParts1, subParts2, units);
303
278
  }
304
279
  }
305
280
 
@@ -4,7 +4,6 @@ import * as ui from 'datagrok-api/ui';
4
4
 
5
5
  import {UnitsHandler} from '@datagrok-libraries/bio/src/utils/units-handler';
6
6
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
7
- import {NotationConverter} from '@datagrok-libraries/bio/src/utils/notation-converter';
8
7
 
9
8
  import {_package} from '../package';
10
9
 
@@ -15,9 +14,9 @@ export function addCopyMenuUI(cell: DG.Cell, menu: DG.Menu): void {
15
14
 
16
15
  menu.group('Copy')
17
16
  .items(tgtNotationList, (tgtNotation) => {
18
- const nc = new NotationConverter(cell.column);
17
+ const ncUH = UnitsHandler.getOrCreate(cell.column);
19
18
  const separator = tgtNotation === NOTATION.SEPARATOR ? _package.properties.DefaultSeparator : undefined;
20
- const converter = nc.getConverter(tgtNotation as NOTATION, separator);
19
+ const converter = ncUH.getConverter(tgtNotation as NOTATION, separator);
21
20
  const tgtSeq = converter(cell.value);
22
21
 
23
22
  if (!navigator.clipboard) {
@@ -5,7 +5,6 @@ import * as grok from 'datagrok-api/grok';
5
5
  import $ from 'cash-dom';
6
6
  import {Subscription} from 'rxjs';
7
7
  import {NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
8
- import {NotationConverter} from '@datagrok-libraries/bio/src/utils/notation-converter';
9
8
  import {UnitsHandler} from '@datagrok-libraries/bio/src/utils/units-handler';
10
9
  import {expect} from '@datagrok-libraries/utils/src/test';
11
10
 
@@ -22,8 +21,8 @@ export function convert(col?: DG.Column): void {
22
21
  let tgtCol = col ?? grok.shell.t.columns.bySemType('Macromolecule')!;
23
22
  if (!tgtCol)
24
23
  throw new Error('No column with Macromolecule semantic type found');
25
- let converter = new NotationConverter(tgtCol);
26
- let currentNotation: NOTATION = converter.notation;
24
+ let converterUH = UnitsHandler.getOrCreate(tgtCol);
25
+ let currentNotation: NOTATION = converterUH.notation;
27
26
  const dialogHeader = ui.divText(
28
27
  'Current notation: ' + currentNotation,
29
28
  {
@@ -47,8 +46,8 @@ export function convert(col?: DG.Column): void {
47
46
  }
48
47
 
49
48
  tgtCol = newCol;
50
- converter = new NotationConverter(tgtCol);
51
- currentNotation = converter.notation;
49
+ converterUH = UnitsHandler.getOrCreate(tgtCol);
50
+ currentNotation = converterUH.notation;
52
51
  if (currentNotation === NOTATION.HELM)
53
52
  separatorInput.value = '/'; // helm monomers can have - in the name like D-aThr;
54
53
  dialogHeader.textContent = 'Current notation: ' + currentNotation;
@@ -117,8 +116,8 @@ export function convert(col?: DG.Column): void {
117
116
  * @param {string | null} separator Separator for SEPARATOR notation
118
117
  */
119
118
  export async function convertDo(srcCol: DG.Column, targetNotation: NOTATION, separator?: string): Promise<DG.Column> {
120
- const converter = new NotationConverter(srcCol);
121
- const newColumn = converter.convert(targetNotation, separator);
119
+ const converterUH = UnitsHandler.getOrCreate(srcCol);
120
+ const newColumn = converterUH.convert(targetNotation, separator);
122
121
  srcCol.dataFrame.columns.add(newColumn);
123
122
 
124
123
  // Call detector directly to escape some error on detectSemanticTypes