@datagrok/bio 2.15.2 → 2.15.5

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.
Files changed (54) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/detectors.js +3 -1
  3. package/dist/284.js +1 -1
  4. package/dist/284.js.map +1 -1
  5. package/dist/455.js +2 -0
  6. package/dist/455.js.map +1 -0
  7. package/dist/980.js +1 -1
  8. package/dist/980.js.map +1 -1
  9. package/dist/package-test.js +3 -3
  10. package/dist/package-test.js.map +1 -1
  11. package/dist/package.js +2 -2
  12. package/dist/package.js.map +1 -1
  13. package/files/tests/to-atomic-level-msa-fasta-output.csv +683 -683
  14. package/files/tests/to-atomic-level-msa-separator-output.csv +104 -104
  15. package/package.json +9 -9
  16. package/src/analysis/sequence-activity-cliffs.ts +3 -1
  17. package/src/calculations/monomerLevelMols.ts +2 -1
  18. package/src/demo/bio03-atomic-level.ts +1 -1
  19. package/src/package-test.ts +6 -1
  20. package/src/package.ts +151 -38
  21. package/src/tests/WebLogo-positions-test.ts +1 -1
  22. package/src/tests/bio-tests.ts +1 -1
  23. package/src/tests/detectors-tests.ts +10 -10
  24. package/src/tests/monomer-libraries-tests.ts +1 -1
  25. package/src/tests/seq-handler-splitted-tests.ts +6 -2
  26. package/src/tests/splitters-test.ts +6 -6
  27. package/src/tests/to-atomic-level-tests.ts +21 -14
  28. package/src/tests/to-atomic-level-ui-tests.ts +75 -35
  29. package/src/tests/utils.ts +2 -2
  30. package/src/utils/cell-renderer-custom.ts +62 -0
  31. package/src/utils/cell-renderer.ts +58 -126
  32. package/src/utils/cyclized.ts +28 -14
  33. package/src/utils/dimerized.ts +0 -2
  34. package/src/utils/helm-to-molfile/converter/converter.ts +75 -54
  35. package/src/utils/helm-to-molfile/converter/monomer-wrapper.ts +2 -2
  36. package/src/utils/helm-to-molfile/converter/polymer.ts +23 -16
  37. package/src/utils/helm-to-molfile/converter/types.ts +0 -10
  38. package/src/utils/helm-to-molfile/utils.ts +10 -7
  39. package/src/utils/monomer-cell-renderer.ts +8 -4
  40. package/src/utils/monomer-lib/lib-manager.ts +2 -2
  41. package/src/utils/monomer-lib/monomer-colors.ts +68 -0
  42. package/src/utils/monomer-lib/monomer-lib-base.ts +165 -0
  43. package/src/utils/monomer-lib/monomer-lib.ts +19 -68
  44. package/src/utils/monomer-lib/web-editor-monomer-dummy.ts +121 -0
  45. package/src/utils/monomer-lib/web-editor-monomer-of-library.ts +102 -0
  46. package/src/utils/save-as-fasta.ts +1 -1
  47. package/src/utils/seq-helper/seq-helper.ts +20 -49
  48. package/src/utils/sequence-to-mol.ts +24 -28
  49. package/src/viewers/web-logo-viewer.ts +2 -1
  50. package/src/widgets/composition-analysis-widget.ts +4 -3
  51. package/src/widgets/representations.ts +8 -10
  52. package/dist/248.js +0 -2
  53. package/dist/248.js.map +0 -1
  54. package/src/utils/cell-renderer-consts.ts +0 -31
@@ -0,0 +1,121 @@
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 {
6
+ HelmType, PolymerType, MonomerType,
7
+ IWebEditorMonomer, WebEditorRGroups
8
+ } from '@datagrok-libraries/bio/src/helm/types';
9
+
10
+ /* eslint-disable camelcase */
11
+ export abstract class WebEditorMonomerDummy implements IWebEditorMonomer {
12
+ //@formatter:off
13
+ public abstract get backgroundcolor(): string | undefined;
14
+ public abstract get linecolor(): string | undefined;
15
+ public abstract get textcolor(): string | undefined;
16
+ //@formatter:on
17
+
18
+ get issmiles(): boolean { return !!this.smiles; }
19
+
20
+ /** R-Group index os single digit only is allowed in Pistoia code */
21
+ public readonly at: WebEditorRGroups = {
22
+ R1: 'H', R2: 'H', R3: 'H', R4: 'H', R5: 'H', R6: 'H', R7: 'H', R8: 'H', R9: 'H'
23
+ };
24
+
25
+ public get rs(): number { return Object.keys(this.at).length; }
26
+
27
+ protected constructor(
28
+ public readonly biotype: string,
29
+ /** symbol */ public readonly id: string,
30
+ /** name */ public readonly n: string | undefined = 'missing',
31
+ /** molfile */ public readonly m: string | undefined = undefined,
32
+ /* Pistoia.HELM deletes .type and .mt in Monomers.addOneMonomer() */
33
+ /** polymer type */ public readonly type: PolymerType | undefined = undefined,
34
+ /** monomer type */ public readonly mt: MonomerType | undefined = undefined,
35
+ public readonly smiles?: string,
36
+ ) {
37
+ if (!this.id)
38
+ throw new Error('Invalid arg undefined [id].');
39
+
40
+ // return new Proxy(this, {
41
+ // get: (target: any, prop: string | symbol, _receiver: any) => {
42
+ // const logPrefix = `${this.toLog()}.proxy.get( '${String(prop)}' )`;
43
+ // switch (prop) {
44
+ // case 'id':
45
+ // case 'at':
46
+ // case 'na':
47
+ // case 'nature':
48
+ // case 'backgroundcolor':
49
+ // case 'linecolor':
50
+ // case 'textcolor': {
51
+ // // these attributes are known and handled
52
+ // return target[prop];
53
+ // }
54
+ // case 'rs': {
55
+ // /* R-Group count (?), 2 is default for monomer "?" */
56
+ // throw new Error('Not supported get "rs" attribute.');
57
+ // }
58
+ // default:
59
+ // // Unexpected attribute requested
60
+ // _package.logger.warning(`${logPrefix}`);
61
+ // return target[prop];
62
+ // }
63
+ // },
64
+ // set: (target, prop, value: any, _receiver: any): boolean => {
65
+ // throw new Error(`Not supported set '${String(prop)}' attribute, any.`);
66
+ // },
67
+ // apply: (target: any, thisArg: any, argArray: any[]): any | undefined => {
68
+ // throw new Error(`Not supported call (apply) '${thisArg.toString()}' method, any.`);
69
+ // }
70
+ // });
71
+ }
72
+
73
+ private static objCounter: number = -1;
74
+ private readonly objId: number = ++WebEditorMonomerDummy.objCounter;
75
+
76
+ private readonly className: string = 'WebEditorMonomerDummy';
77
+
78
+ protected toLog(): string {
79
+ return `Helm: ${this.className}<${this.objId}>`;
80
+ }
81
+ }
82
+
83
+ export class GapWebEditorMonomer extends WebEditorMonomerDummy {
84
+ public readonly backgroundcolor: string = '#FFFFFF';
85
+ public readonly linecolor: string = '#808080';
86
+ public readonly textcolor: string = '#808080';
87
+
88
+ constructor(biotype: string, id: string) {
89
+ super(biotype, id, 'gap');
90
+ }
91
+ }
92
+
93
+ export class AmbiguousWebEditorMonomer extends WebEditorMonomerDummy {
94
+ public readonly backgroundcolor: string = '#808080';
95
+ public readonly linecolor: string = '#000000';
96
+ public readonly textcolor: string = '#000000';
97
+
98
+ constructor(biotype: string, id: string) {
99
+ super(biotype, id, 'ambiguous');
100
+ }
101
+ }
102
+
103
+ export class MissingWebEditorMonomer extends WebEditorMonomerDummy {
104
+ public readonly backgroundcolor: string = '#FF4444';
105
+ public readonly linecolor: string = '#800000';
106
+ public readonly textcolor: string = '#FFFFFF';
107
+
108
+ constructor(biotype: string, id: string) {
109
+ super(biotype, id, 'missing');
110
+ }
111
+ }
112
+
113
+ export class BrokenWebEditorMonomer extends WebEditorMonomerDummy {
114
+ public readonly backgroundcolor: string = '#FFFF44';
115
+ public readonly linecolor: string = '#800000';
116
+ public readonly textcolor: string = '#000000';
117
+
118
+ constructor(biotype: string, id: string) {
119
+ super(biotype, id, 'broken');
120
+ }
121
+ }
@@ -0,0 +1,102 @@
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 {HelmType, IMonomerColors, IWebEditorMonomer, MonomerType, PolymerType, WebEditorRGroups} from '@datagrok-libraries/bio/src/helm/types';
6
+ import {IMonomerLibBase, Monomer} from '@datagrok-libraries/bio/src/types/index';
7
+ import {HELM_OPTIONAL_FIELDS as OPT, HELM_REQUIRED_FIELD as REQ, HELM_RGROUP_FIELDS as RGP} from '@datagrok-libraries/bio/src/utils/const';
8
+
9
+ import {BrokenWebEditorMonomer, MissingWebEditorMonomer} from './web-editor-monomer-dummy';
10
+ import {naturalMonomerColors} from './monomer-colors';
11
+
12
+ export class LibraryWebEditorMonomer implements IWebEditorMonomer {
13
+ public get rs(): number { return Object.keys(this.at).length; }
14
+
15
+ public get issmiles(): boolean { return !!this.smiles; }
16
+
17
+ public linecolor?: string;
18
+ public backgroundcolor?: string;
19
+ public textcolor?: string;
20
+
21
+ /* eslint-disable max-params */
22
+ protected constructor(
23
+ public readonly id: string,
24
+ public readonly m: string,
25
+ public readonly n: string,
26
+ public readonly na: string | undefined,
27
+ public readonly type: PolymerType,
28
+ public readonly mt: MonomerType,
29
+ public readonly at: WebEditorRGroups,
30
+ public readonly smiles?: string,
31
+ ) /* eslint-enable max-params */ {}
32
+
33
+ static fromMonomer(biotype: HelmType, monomer: Monomer, monomerLib: IMonomerLibBase): IWebEditorMonomer {
34
+ let at: WebEditorRGroups = {};
35
+ const symbol = monomer[REQ.SYMBOL];
36
+ const smiles = monomer[REQ.SMILES];
37
+ if (monomer.rgroups.length > 0) {
38
+ monomer.rgroups.forEach((it) => {
39
+ at[it[RGP.LABEL]] = it[RGP.CAP_GROUP_NAME];
40
+ });
41
+ } else if (smiles) {
42
+ // Generate R-Groups from SMILES
43
+ at = monomerLib.getRS(smiles);
44
+ } else if (!monomer.lib) {
45
+ // missing
46
+ return new MissingWebEditorMonomer(biotype, symbol);
47
+ } else {
48
+ // broken
49
+ return new BrokenWebEditorMonomer(biotype, symbol);
50
+ }
51
+
52
+ const res = new LibraryWebEditorMonomer(
53
+ monomer[REQ.SYMBOL],
54
+ monomer[REQ.MOLFILE],
55
+ monomer[REQ.NAME],
56
+ monomer[OPT.NATURAL_ANALOG],
57
+ monomer[REQ.POLYMER_TYPE],
58
+ monomer[REQ.MONOMER_TYPE],
59
+ at);
60
+
61
+ const colors = getMonomerColors(biotype, monomer);
62
+ if (colors) {
63
+ res.textcolor = colors?.textcolor;
64
+ res.linecolor = colors?.linecolor;
65
+ res.backgroundcolor = colors?.backgroundcolor;
66
+ }
67
+
68
+ return res;
69
+ }
70
+ }
71
+
72
+ function getMonomerColors(biotype: HelmType, monomer: Monomer): IMonomerColors | null {
73
+ const currentMonomerSchema = 'default';
74
+ let monomerSchema: string = currentMonomerSchema;
75
+
76
+ let res: any;
77
+ if (monomer.meta && monomer.meta.colors) {
78
+ const monomerColors: { [colorSchemaName: string]: any } = monomer.meta.colors;
79
+ if (!(currentMonomerSchema in monomerColors)) monomerSchema = 'default';
80
+ let res = monomerColors[monomerSchema];
81
+ }
82
+
83
+ if (!res) {
84
+ const biotypeColors: { [symbol: string]: string } | undefined = naturalMonomerColors[biotype];
85
+ const nColor = biotypeColors?.[monomer.symbol];
86
+ if (nColor)
87
+ res = {textColor: "#000000", lineColor: "#000000", backgroundColor: nColor};
88
+ }
89
+
90
+ const na = monomer[OPT.NATURAL_ANALOG];
91
+ if (!res && na) {
92
+ const biotypeColors: { [symbol: string]: string } | undefined = naturalMonomerColors[biotype];
93
+ const naColor = biotypeColors?.[na];
94
+ res = {textColor: "#000000", lineColor: "#000000", backgroundColor: naColor ?? "#FFFFFF",};
95
+ }
96
+
97
+ return !res ? null : {
98
+ textcolor: res.text ?? res.textColor,
99
+ linecolor: res.line ?? res.lineColor,
100
+ backgroundcolor: res.background ?? res.backgroundColor
101
+ } as IMonomerColors;
102
+ }
@@ -105,7 +105,7 @@ export function wrapSequence(srcSS: ISeqSplitted, lineWidth: number = FASTA_LINE
105
105
  const seqLineList: string[] = [];
106
106
  while (seqPos < seqLength) {
107
107
  /* join sliced monomer into line */
108
- const seqLine = wu(srcSS.originals).slice(seqPos, seqPos + lineWidth).toArray();
108
+ const seqLine = wu.count(seqPos).take(Math.min(srcSS.length - seqPos, lineWidth)).map((p) => srcSS.getOriginal(p)).toArray();
109
109
  const seqLineTxt: string = seqLine.map((om) => om.length > 1 ? `[${om}]` : om)
110
110
  .reduce((a, b) => a + b, '');
111
111
  seqLineList.push(seqLineTxt);
@@ -4,18 +4,20 @@ import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import wu from 'wu';
6
6
 
7
- import {ISeqHelper, ISubstruct, SUBSTRUCT_COL, ToAtomicLevelResType} from '@datagrok-libraries/bio/src/utils/seq-helper';
7
+ import {ISeqHelper, ToAtomicLevelRes} from '@datagrok-libraries/bio/src/utils/seq-helper';
8
8
  import {RDModule, RDMol} from '@datagrok-libraries/chem-meta/src/rdkit-api';
9
9
  import {IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
10
10
  import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
11
- import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
11
+ import {MolfileWithMap} from '@datagrok-libraries/bio/src/monomer-works/types';
12
+ import {getMolColName, hexToPercentRgb} from '@datagrok-libraries/bio/src/monomer-works/utils';
13
+ import {ChemTags} from '@datagrok-libraries/chem-meta/src/consts';
14
+ import {getMolHighlight} from '@datagrok-libraries/bio/src/monomer-works/seq-to-molfile';
15
+ import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/index';
12
16
 
13
17
  import {HelmToMolfileConverter} from '../helm-to-molfile/converter';
14
- import {Column, DataFrame} from 'datagrok-api/dg';
15
- import {MolfileWithMap, MonomerMap} from '../helm-to-molfile/converter/types';
18
+ import {MonomerLibManager} from '../monomer-lib/lib-manager';
16
19
 
17
20
  import {_package, getMonomerLibHelper} from '../../package';
18
- import {MonomerLibManager} from '../monomer-lib/lib-manager';
19
21
 
20
22
  type SeqHelperWindowType = Window & { $seqHelperPromise?: Promise<SeqHelper> };
21
23
  declare const window: SeqHelperWindowType;
@@ -27,27 +29,23 @@ export class SeqHelper implements ISeqHelper {
27
29
  private readonly rdKitModule: RDModule
28
30
  ) {}
29
31
 
30
- getHelmToMolfileConverter(df: DataFrame, helmCol: Column<string>) {
31
- return new HelmToMolfileConverter(helmCol, df, this.libHelper, this.helmHelper);
32
+ getHelmToMolfileConverter(monomerLib: IMonomerLibBase): HelmToMolfileConverter {
33
+ return new HelmToMolfileConverter(this.helmHelper, this.rdKitModule, monomerLib);
32
34
  }
33
35
 
34
36
  async helmToAtomicLevel(
35
- helmCol: DG.Column<string>, chiralityEngine?: boolean, highlight?: boolean
36
- ): Promise<ToAtomicLevelResType> {
37
- const getUnusedName = (df: DG.DataFrame | undefined, colName: string): string => {
38
- if (!df) return colName;
39
- return df.columns.getUnusedName(colName);
40
- };
37
+ helmCol: DG.Column<string>, chiralityEngine?: boolean, highlight?: boolean, overrideMonomerLib?: IMonomerLibBase
38
+ ): Promise<ToAtomicLevelRes> {
39
+ const monomerLib: IMonomerLibBase = overrideMonomerLib ?? this.libHelper.getMonomerLib();
41
40
 
42
41
  const df: DG.DataFrame = helmCol.dataFrame;
43
- const molColName: string = getUnusedName(df, `molfile(${helmCol})`);
44
- const molHlColName: string = getUnusedName(df, `~${molColName}-hl`);
42
+ const molColName: string = getMolColName(df, helmCol.name);
45
43
 
46
- const converter = this.getHelmToMolfileConverter(df, helmCol);
44
+ const converter = this.getHelmToMolfileConverter(monomerLib);
47
45
 
48
46
  //#region From HelmToMolfileConverter.convertToRdKitBeautifiedMolfileColumn
49
47
 
50
- const molfilesV3K = converter.convertToMolfileV3K(this.rdKitModule);
48
+ const molfilesV3K = converter.convertToMolfileV3K(helmCol, this.rdKitModule, monomerLib);
51
49
 
52
50
  const beautifiedMolList: (RDMol | null)[] = molfilesV3K.map((item) => {
53
51
  const molfile = item.molfile;
@@ -78,41 +76,14 @@ export class SeqHelper implements ISeqHelper {
78
76
 
79
77
  //#endregion From HelmToMolfileConverter
80
78
 
81
- const molHlList = molfilesV3K.map((item: MolfileWithMap) => {
82
- const mmList: MonomerMap[] = item.monomers;
83
-
84
- const hlAtoms: { [key: number]: number[] } = {};
85
- const hlBonds: { [key: number]: number[] } = {};
86
-
87
- for (const [mm, mmI] of wu.enumerate(mmList)) {
88
- if (mmI >= 2) continue;
89
-
90
- const mmColor = [Math.random(), Math.random(), Math.random(), 0.3]; // green color
91
- for (const mAtom of mm.atoms) {
92
- hlAtoms[mAtom] = mmColor;
93
- }
94
- for (const mBond of mm.bonds) {
95
- hlBonds[mBond] = mmColor;
96
- }
97
- }
98
-
99
- let resSubstruct: ISubstruct = {
100
- atoms: Object.keys(hlAtoms).map((k) => parseInt(k)),
101
- bonds: Object.keys(hlBonds).map((k) => parseInt(k)),
102
- highlightAtomColors: hlAtoms,
103
- highlightBondColors: hlBonds,
104
- };
105
-
106
- return resSubstruct;
107
- });
79
+ const molHlList = molfilesV3K.map((item: MolfileWithMap) => getMolHighlight(item.monomers.values(), monomerLib));
108
80
 
109
81
  const molCol = DG.Column.fromStrings(molColName, molList);
110
- molCol.semType = 'Molecule';
111
- molCol.temp[SUBSTRUCT_COL] = molHlColName;
112
- const molHlCol = DG.Column.fromList(DG.COLUMN_TYPE.OBJECT, molHlColName, molHlList);
113
- molHlCol.semType = 'Molecule-substruct';
82
+ molCol.semType = DG.SEMTYPE.MOLECULE;
83
+ molCol.meta.units = DG.UNITS.Molecule.MOLBLOCK;
84
+ molCol.setTag(ChemTags.SEQUENCE_SRC_COL, helmCol.name);
114
85
 
115
- return {molCol: molCol, molHighlightCol: molHlCol};
86
+ return {molCol: molCol, warnings: []};
116
87
  }
117
88
 
118
89
  static getInstance(): Promise<SeqHelper> {
@@ -6,30 +6,23 @@ import {_toAtomicLevel} from '@datagrok-libraries/bio/src/monomer-works/to-atomi
6
6
  import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
7
7
  import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
8
8
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
9
- import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
10
- import {getSeqHelper, ToAtomicLevelResType} from '@datagrok-libraries/bio/src/utils/seq-helper';
9
+ import {getSeqHelper, ToAtomicLevelRes} from '@datagrok-libraries/bio/src/utils/seq-helper';
11
10
  import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
11
+ import {ChemTags, ChemTemps} from '@datagrok-libraries/chem-meta/src/consts';
12
+ import {buildMonomerHoverLink} from '@datagrok-libraries/bio/src/monomer-works/monomer-hover';
12
13
 
13
14
  import {checkInputColumnUI} from './check-input-column';
15
+ import {getMolColName} from '@datagrok-libraries/bio/src/monomer-works/utils';
14
16
 
15
17
  export async function sequenceToMolfile(
16
- df: DG.DataFrame, macroMolecule: DG.Column, nonlinear: boolean, monomerLib: IMonomerLib
17
- ): Promise<DG.Column<string> | null> {
18
- let rdKitModule: RDModule;
19
- try {
20
- rdKitModule = await getRdKitModule();
21
- } catch (ex: any) {
22
- grok.shell.warning('Transformation to atomic level requires package "Chem" installed.');
23
- return null;
24
- }
25
-
26
- let resCol: DG.Column<string> | null = null;
18
+ df: DG.DataFrame, macroMolecule: DG.Column, nonlinear: boolean, highlight: boolean,
19
+ monomerLib: IMonomerLib, rdKitModule: RDModule
20
+ ): Promise<ToAtomicLevelRes> {
21
+ let res: ToAtomicLevelRes;
27
22
  if (nonlinear) {
28
23
  const seqHelper = await getSeqHelper();
29
24
  const seqSh = SeqHandler.forColumn(macroMolecule);
30
25
 
31
- let atomicLevelRes: ToAtomicLevelResType;
32
-
33
26
  let helmCol: DG.Column<string>;
34
27
  let seqColName!: string;
35
28
  if (seqSh.isHelm())
@@ -42,25 +35,28 @@ export async function sequenceToMolfile(
42
35
  df.columns.add(helmCol, false);
43
36
  }
44
37
  try {
45
- atomicLevelRes = await seqHelper.helmToAtomicLevel(helmCol, true, true);
38
+ res = await seqHelper.helmToAtomicLevel(helmCol, true, true);
46
39
  } finally {
47
40
  if (helmCol !== macroMolecule) {
48
41
  df.columns.remove(helmCol.name);
49
42
  macroMolecule.name = seqColName;
50
43
  }
51
44
  }
52
- df.columns.add(atomicLevelRes.molCol);
53
- df.columns.add(atomicLevelRes.molHighlightCol);
54
- resCol = atomicLevelRes.molCol;
55
- } else {
45
+ } else { // linear
56
46
  if (!checkInputColumnUI(macroMolecule, 'To Atomic Level'))
57
- return null;
58
- const atomicLevelRes = await _toAtomicLevel(df, macroMolecule, monomerLib);
59
- if (atomicLevelRes.col !== null) {
60
- df.columns.add(atomicLevelRes.col, true);
61
- resCol = atomicLevelRes.col;
62
- }
47
+ return {molCol: null, warnings: ['Column is not suitable']};
48
+
49
+ res = await _toAtomicLevel(df, macroMolecule, monomerLib, rdKitModule);
50
+ }
51
+
52
+ if (res.molCol) {
53
+ const molColName = getMolColName(df, macroMolecule.name);
54
+ res.molCol.name = molColName;
55
+ df.columns.add(res.molCol, true);
56
+
57
+ buildMonomerHoverLink(macroMolecule, res.molCol, monomerLib, rdKitModule);
58
+ res.molCol.setTag(ChemTags.SEQUENCE_SRC_HL_MONOMERS, String(highlight));
59
+ await grok.data.detectSemanticTypes(df);
63
60
  }
64
- if (resCol) await grok.data.detectSemanticTypes(df);
65
- return resCol;
61
+ return res;
66
62
  }
@@ -17,9 +17,10 @@ import {
17
17
  } from '@datagrok-libraries/bio/src/viewers/web-logo';
18
18
  import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
19
19
  import {intToHtmlA} from '@datagrok-libraries/utils/src/color';
20
- import {GAP_SYMBOL, ISeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
20
+ import {ISeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
21
21
  import {testEvent} from '@datagrok-libraries/utils/src/test';
22
22
  import {PromiseSyncer} from '@datagrok-libraries/bio/src/utils/syncer';
23
+ import {GAP_SYMBOL} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
23
24
 
24
25
  import {AggFunc, getAgg} from '../utils/agg';
25
26
  import {buildCompositionTable} from '../widgets/composition-analysis-widget';
@@ -9,7 +9,7 @@ import {SeqPalette} from '@datagrok-libraries/bio/src/seq-palettes';
9
9
  import {UnknownSeqPalettes} from '@datagrok-libraries/bio/src/unknown';
10
10
  import '../../css/composition-analysis.css';
11
11
  import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
12
- import {GAP_SYMBOL} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
12
+ import {GAP_SYMBOL} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
13
13
 
14
14
 
15
15
  export function getCompositionAnalysisWidget(val: DG.SemanticValue): DG.Widget {
@@ -32,8 +32,9 @@ export function getCompositionAnalysisWidget(val: DG.SemanticValue): DG.Widget {
32
32
  const counts: { [m: string]: number } = {};
33
33
  const sh = SeqHandler.forColumn(val.cell.column as DG.Column<string>);
34
34
  const rowIdx = val.cell.rowIndex;
35
- const parts = sh.getSplitted(rowIdx);
36
- wu(parts.canonicals).filter((cm) => cm !== GAP_SYMBOL).forEach((cm) => {
35
+ const seqSS = sh.getSplitted(rowIdx);
36
+ wu.count(0).take(seqSS.length).filter((posIdx) => !seqSS.isGap(posIdx)).forEach((posIdx) => {
37
+ const cm = seqSS.getCanonical(posIdx);
37
38
  const count = counts[cm] || 0;
38
39
  counts[cm] = count + 1;
39
40
  });
@@ -5,9 +5,7 @@ import * as DG from 'datagrok-api/dg';
5
5
  import {getMolfilesFromSingleSeq} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
6
6
  import {TAGS as mmcrTAGS} from '@datagrok-libraries/bio/src/utils/cell-renderer';
7
7
 
8
- import {
9
- Temps as mmcrTemps, rendererSettingsChangedState, Temps
10
- } from '../utils/cell-renderer-consts';
8
+ import {MmcrTemps, rendererSettingsChangedState} from '@datagrok-libraries/bio/src/utils/cell-renderer-consts';
11
9
 
12
10
  import {_package} from '../package';
13
11
  import {max} from 'rxjs/operators';
@@ -30,8 +28,8 @@ export function getMacromoleculeColumnPropertyPanel(col: DG.Column): DG.Widget {
30
28
  const v = parseInt(col.getTag(mmcrTAGS.maxMonomerLength));
31
29
  maxMonomerLength = !isNaN(v) ? v : maxMonomerLength;
32
30
  }
33
- if (Temps.maxMonomerLength in col.temp) {
34
- const v = parseInt(col.temp[Temps.maxMonomerLength]);
31
+ if (MmcrTemps.maxMonomerLength in col.temp) {
32
+ const v = parseInt(col.temp[MmcrTemps.maxMonomerLength]);
35
33
  maxMonomerLength = !isNaN(v) ? v : maxMonomerLength;
36
34
  }
37
35
  const maxMonomerLengthInput = ui.input.int('Max Monomer Length', {
@@ -43,8 +41,8 @@ export function getMacromoleculeColumnPropertyPanel(col: DG.Column): DG.Widget {
43
41
  else {
44
42
  const newValue = value ?? '';
45
43
  const tagValue = newValue == null ? '' : newValue.toString();
46
- col.temp[Temps.maxMonomerLength] = tagValue;
47
- col.temp[Temps.rendererSettingsChanged] = rendererSettingsChangedState.true;
44
+ col.temp[MmcrTemps.maxMonomerLength] = tagValue;
45
+ col.temp[MmcrTemps.rendererSettingsChanged] = rendererSettingsChangedState.true;
48
46
  col.dataFrame.fireValuesChanged();
49
47
  }
50
48
  },
@@ -52,10 +50,10 @@ export function getMacromoleculeColumnPropertyPanel(col: DG.Column): DG.Widget {
52
50
  });
53
51
 
54
52
  const gapLengthInput = ui.input.int('Monomer Margin', {
55
- value: col.temp[mmcrTemps.gapLength] ?? 0,
53
+ value: col.temp[MmcrTemps.gapLength] ?? 0,
56
54
  onValueChanged: (value) => {
57
- col.temp[mmcrTemps.gapLength] = value;
58
- col.temp[mmcrTemps.rendererSettingsChanged] = rendererSettingsChangedState.true;
55
+ col.temp[MmcrTemps.gapLength] = value;
56
+ col.temp[MmcrTemps.rendererSettingsChanged] = rendererSettingsChangedState.true;
59
57
  col.dataFrame.fireValuesChanged();
60
58
  },
61
59
  tooltipText: 'The size of margin between monomers (in pixels)'
package/dist/248.js DELETED
@@ -1,2 +0,0 @@
1
- var bio;(()=>{"use strict";const t={V2K_RGP_SHIFT:8,V2K_RGP_LINE:"M RGP",V2K_A_LINE:"A ",V3K_COUNTS_SHIFT:14,V3K_IDX_SHIFT:7,V3K_HEADER_FIRST_LINE:"\nDatagrok macromolecule handler\n\n",V3K_HEADER_SECOND_LINE:" 0 0 0 0 0 0 999 V3000\n",V3K_BEGIN_CTAB_BLOCK:"M V30 BEGIN CTAB\n",V3K_END_CTAB_BLOCK:"M V30 END CTAB\n",V3K_BEGIN_COUNTS_LINE:"M V30 COUNTS ",V3K_COUNTS_LINE_ENDING:" 0 0 0\n",V3K_BEGIN_ATOM_BLOCK:"M V30 BEGIN ATOM\n",V3K_END_ATOM_BLOCK:"M V30 END ATOM\n",V3K_BEGIN_BOND_BLOCK:"M V30 BEGIN BOND\n",V3K_END_BOND_BLOCK:"M V30 END BOND\n",V3K_BOND_CONFIG:" CFG=",V3K_BEGIN_DATA_LINE:"M V30 ",V3K_END:"M END",PRECISION_FACTOR:1e4,DEOXYRIBOSE:"d",RIBOSE:"r",PHOSPHATE:"p",OXYGEN:"O",HYDROGEN:"H"};new RegExp("[rd]\\((\\w)\\)p?","g");class n{constructor(t,n,o){this.name=t,this.alphabet=n,this.cutoff=o}}var o,e,a,i;!function(t){t.FASTA="fasta",t.SEPARATOR="separator",t.HELM="helm"}(o||(o={})),(i=e||(e={})).DNA="DNA",i.RNA="RNA",i.PT="PT",i.UN="UN",function(t){t.aligned="aligned",t.alphabet="alphabet",t.alphabetSize=".alphabetSize",t.alphabetIsMultichar=".alphabetIsMultichar",t.separator="separator",t.isHelmCompatible=".isHelmCompatible",t.positionNames=".positionNames",t.positionLabels=".positionLabels",t.regions=".regions"}(a||(a={}));const s=new class{constructor(){this.fasta={peptide:new Set(["G","L","Y","S","E","Q","D","N","F","A","K","R","H","C","V","P","W","I","M","T"]),dna:new Set(["A","C","G","T"]),rna:new Set(["A","C","G","U"])}}};function h(n,o,a,i){if(0===n.length)return"";const s=f,{atomCount:h,bondCount:r}=s(n,o,a,i),c=new Array(h),E=new Array(r);let b,S=null,A=null;"PEPTIDE"===i?b=N:(b=_,S=a===e.DNA?o.get(t.DEOXYRIBOSE):o.get(t.RIBOSE),A=o.get(t.PHOSPHATE));const d={i:0,nodeShift:0,bondShift:0,backbonePositionShift:new Array(2).fill(0),branchPositionShift:new Array(2).fill(0),backboneAttachNode:0,branchAttachNode:0,flipFactor:1},m={sugar:S,phosphate:A,seqLength:n.length,atomCount:h,bondCount:r},I=[];let g=0;for(d.i=0;d.i<m.seqLength;++d.i){const t=o.get(n[d.i]);b(t,c,E,d,m),t.stereoAtoms?.forEach((t=>I.push(t+g))),g+=t.atoms.x.length}!function(n,o,e,a){const i=e.nodeShift+1;n[a.atomCount]=t.V3K_BEGIN_DATA_LINE+i+" "+t.OXYGEN+" "+l(e.backbonePositionShift[0])+" "+e.flipFactor*l(e.backbonePositionShift[1])+" 0.000000 0\n";const s=e.backboneAttachNode,h=i;o[a.bondCount]=t.V3K_BEGIN_DATA_LINE+e.bondShift+" 1 "+s+" "+h+"\n"}(c,E,d,m);const O=t.V3K_BEGIN_COUNTS_LINE+h+" "+r+t.V3K_COUNTS_LINE_ENDING;let T="";return T+=t.V3K_HEADER_FIRST_LINE,T+=t.V3K_HEADER_SECOND_LINE,T+=t.V3K_BEGIN_CTAB_BLOCK,T+=O,T+=t.V3K_BEGIN_ATOM_BLOCK,T+=c.join(""),T+=t.V3K_END_ATOM_BLOCK,T+=t.V3K_BEGIN_BOND_BLOCK,T+=E.join(""),T+=t.V3K_END_BOND_BLOCK,I.length>0&&(T+=function(t){const n=[];let o=`M V30 MDLV30/STEABS ATOMS=(${t.length}`;for(let e=0;e<t.length;e++){const a=`${o} ${t[e]}`;a.length>76?(n.push(`${o} -\n`),o=`M V30 ${t[e]}`):o=a,e===t.length-1&&n.push(`${o})\n`)}return`M V30 BEGIN COLLECTION\n${n.join("")}M V30 END COLLECTION\n`}(I)),T+=t.V3K_END_CTAB_BLOCK,T+=t.V3K_END,T}function N(t,n,o,e){e.flipFactor=(-1)**(e.i%2),r(t,n,o,e)}function r(n,o,e,a){!function(n,o,e){for(let a=0;a<n.atoms.atomTypes.length;++a){const i=e.nodeShift+a+1;o[e.nodeShift+a]=t.V3K_BEGIN_DATA_LINE+i+" "+n.atoms.atomTypes[a]+" "+l(e.backbonePositionShift[0]+n.atoms.x[a])+" "+l(e.backbonePositionShift[1]+e.flipFactor*n.atoms.y[a])+" "+n.atoms.kwargs[a]}}(n,o,a),c(n,e,a),function(n,o,e){if(0!==e.backboneAttachNode){const a=e.bondShift,i=e.backboneAttachNode,s=n.meta.terminalNodes[0]+e.nodeShift;o[e.bondShift-1]=t.V3K_BEGIN_DATA_LINE+a+" 1 "+i+" "+s+"\n"}}(n,e,a),null!==n.meta.branchShift&&n.meta.terminalNodes.length>2&&function(t,n){n.branchAttachNode=n.nodeShift+t.meta.terminalNodes[2];for(let o=0;o<2;++o)n.branchPositionShift[o]=n.backbonePositionShift[o]+t.meta.branchShift[o]}(n,a),function(t,n){n.backboneAttachNode=n.nodeShift+t.meta.terminalNodes[1],n.bondShift+=t.bonds.atomPairs.length+1,n.nodeShift+=t.atoms.atomTypes.length,n.backbonePositionShift[0]+=t.meta.backboneShift[0],n.backbonePositionShift[1]+=n.flipFactor*t.meta.backboneShift[1]}(n,a)}function _(n,o,e,a,i){if(0===a.i)r(i.sugar,o,e,a);else for(const t of[i.phosphate,i.sugar])r(t,o,e,a);!function(n,o,e,a){(function(n,o,e){for(let a=0;a<n.atoms.atomTypes.length;++a){const i=e.nodeShift+a+1;o[e.nodeShift+a]=t.V3K_BEGIN_DATA_LINE+i+" "+n.atoms.atomTypes[a]+" "+l(e.branchPositionShift[0]+n.atoms.x[a])+" "+l(e.branchPositionShift[1]+e.flipFactor*n.atoms.y[a])+" "+n.atoms.kwargs[a]}})(n,o,a),c(n,e,a),function(n,o,e){const a=e.bondShift,i=e.branchAttachNode,s=n.meta.terminalNodes[0]+e.nodeShift;o[a-1]=t.V3K_BEGIN_DATA_LINE+a+" 1 "+i+" "+s+"\n"}(n,e,a);const i=a.bondShift,s=a.branchAttachNode,h=n.meta.terminalNodes[0]+a.nodeShift;e[i-1]=t.V3K_BEGIN_DATA_LINE+i+" 1 "+s+" "+h+"\n",a.bondShift+=n.bonds.atomPairs.length+1,a.nodeShift+=n.atoms.atomTypes.length}(n,o,e,a)}function c(n,o,e){for(let a=0;a<n.bonds.atomPairs.length;++a){const i=e.bondShift+a+1,s=n.bonds.atomPairs[a][0]+e.nodeShift,h=n.bonds.atomPairs[a][1]+e.nodeShift;let N="";if(n.bonds.bondConfiguration.has(a)){let t=n.bonds.bondConfiguration.get(a);e.flipFactor<0&&(t=1===t?3:1),N=" CFG="+t}const r=n.bonds.kwargs.has(a)?" "+n.bonds.kwargs.get(a):"";o[e.bondShift+a]=t.V3K_BEGIN_DATA_LINE+i+" "+n.bonds.bondTypes[a]+" "+s+" "+h+N+r+"\n"}}function f(n,o,a,i){let s=0,h=0;for(const t of n){if(""===t)continue;const n=o.get(t);s+=n.atoms.x.length,h+=n.bonds.bondTypes.length}if("PEPTIDE"===i)s+=1,h+=n.length;else{const i=a===e.DNA?o.get(t.DEOXYRIBOSE):o.get(t.RIBOSE),N=o.get(t.PHOSPHATE);s+=(n.length-1)*N.atoms.x.length,s+=n.length*i.atoms.x.length,s+=1,h+=(n.length-1)*N.bonds.bondTypes.length,h+=n.length*i.bonds.bondTypes.length,h-=1,h+=3*n.length}return{atomCount:s,bondCount:h}}function l(n){return Math.round(t.PRECISION_FACTOR*n)/t.PRECISION_FACTOR}new n(e.PT,s.fasta.peptide,.5),new n(e.DNA,s.fasta.dna,.55),new n(e.RNA,s.fasta.rna,.55),onmessage=t=>{const{monomerSequencesArray:n,monomersDict:o,alphabet:e,polymerType:a,start:i,end:s}=t.data,N=new Array(s-i),r=new Array(0);for(let t=i;t<s;++t)try{const s=n[t];N[t-i]=h(s,o,e,a)}catch(n){const o=`Cannot get molfile of row #${t}: ${n instanceof Error?n.message:n.toString()}.`;r.push(o)}postMessage({molfileList:N,molfileWarningList:r})},bio={}})();
2
- //# sourceMappingURL=248.js.map
package/dist/248.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"248.js","mappings":"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","sources":["webpack://bio/./node_modules/@datagrok-libraries/bio/src/monomer-works/consts.js","webpack://bio/./node_modules/@datagrok-libraries/bio/src/utils/const.js","webpack://bio/./node_modules/@datagrok-libraries/bio/src/utils/macromolecule/types.js","webpack://bio/./node_modules/@datagrok-libraries/bio/src/utils/macromolecule/consts.js","webpack://bio/./node_modules/@datagrok-libraries/bio/src/monomer-works/to-atomic-level-utils.js","webpack://bio/./node_modules/@datagrok-libraries/bio/src/monomer-works/seq-to-molfile-worker.js"],"sourcesContent":["export const monomerWorksConsts = {\n // constants for parsing molfile V2000\n V2K_RGP_SHIFT: 8,\n V2K_RGP_LINE: 'M RGP',\n V2K_A_LINE: 'A ',\n // constants for parsing/reconstruction of molfile V3000\n V3K_COUNTS_SHIFT: 14,\n V3K_IDX_SHIFT: 7,\n V3K_HEADER_FIRST_LINE: '\\nDatagrok macromolecule handler\\n\\n',\n V3K_HEADER_SECOND_LINE: ' 0 0 0 0 0 0 999 V3000\\n',\n V3K_BEGIN_CTAB_BLOCK: 'M V30 BEGIN CTAB\\n',\n V3K_END_CTAB_BLOCK: 'M V30 END CTAB\\n',\n V3K_BEGIN_COUNTS_LINE: 'M V30 COUNTS ',\n V3K_COUNTS_LINE_ENDING: ' 0 0 0\\n',\n V3K_BEGIN_ATOM_BLOCK: 'M V30 BEGIN ATOM\\n',\n V3K_END_ATOM_BLOCK: 'M V30 END ATOM\\n',\n V3K_BEGIN_BOND_BLOCK: 'M V30 BEGIN BOND\\n',\n V3K_END_BOND_BLOCK: 'M V30 END BOND\\n',\n V3K_BOND_CONFIG: ' CFG=',\n V3K_BEGIN_DATA_LINE: 'M V30 ',\n V3K_END: 'M END',\n PRECISION_FACTOR: 10000, // HELMCoreLibrary has 4 significant digits after decimal point in atom coordinates\n // symbols for the corresponding monomers in HELM library\n DEOXYRIBOSE: 'd',\n RIBOSE: 'r',\n PHOSPHATE: 'p',\n OXYGEN: 'O',\n HYDROGEN: 'H',\n};\n//# sourceMappingURL=consts.js.map","// core fields of HELM library object used in toAtomicLevel function\nexport const HELM_CORE_FIELDS = [\n \"symbol\" /* HELM_FIELDS.SYMBOL */,\n \"molfile\" /* HELM_FIELDS.MOLFILE */,\n \"rgroups\" /* HELM_FIELDS.RGROUPS */,\n \"name\" /* HELM_FIELDS.NAME */,\n // HELM_FIELDS.MONOMER_TYPE, // add if terminal monomers for PEPTIDEs to be\n // supported\n];\nexport const SDF_MONOMER_NAME = 'MonomerName';\n// todo: ideally, keys should be expressed via constants\nexport const jsonSdfMonomerLibDict = {\n 'monomerType': null, // -> Backbone\n 'smiles': null,\n 'name': 'Name',\n 'author': null,\n 'molfile': 'molecule',\n 'naturalAnalog': 'MonomerNaturalAnalogCode',\n 'rgroups': 'MonomerCaps',\n 'createDate': null,\n 'id': null,\n 'polymerType': 'MonomerType',\n 'symbol': 'MonomerName'\n};\nexport const DUMMY_MONOMER = {\n 'monomerType': 'Backbone',\n 'smiles': '',\n 'name': '',\n 'author': 'Datagrok',\n 'molfile': '',\n 'naturalAnalog': '',\n 'rgroups': [],\n 'createDate': null,\n 'id': 0,\n 'polymerType': 'PEPTIDE',\n 'symbol': ''\n};\n// range of hex nubers used in PepSea library to endode monomers\nexport const MONOMER_ENCODE_MIN = 0x100;\nexport const MONOMER_ENCODE_MAX = 0x40A;\nexport const RIBOSE_SYMBOL = 'r';\nexport const DEOXYRIBOSE_SYMBOL = 'd';\nexport const PHOSPHATE_SYMBOL = 'p';\nexport const HELM_WRAPPERS_REGEXP = new RegExp(`[${RIBOSE_SYMBOL}${DEOXYRIBOSE_SYMBOL}]\\\\((\\\\w)\\\\)${PHOSPHATE_SYMBOL}?`, 'g');\n//# sourceMappingURL=const.js.map","/** Canonical gap symbol */\nexport const GAP_SYMBOL = '';\n/** Alphabet candidate type */\nexport class CandidateType {\n constructor(name, alphabet, cutoff) {\n this.name = name;\n this.alphabet = alphabet;\n this.cutoff = cutoff;\n }\n}\n/** Alphabet candidate similarity type */\nexport class CandidateSimType extends CandidateType {\n constructor(candidate, freq, similarity) {\n super(candidate.name, candidate.alphabet, candidate.cutoff);\n this.freq = freq;\n this.similarity = similarity;\n }\n}\n//# sourceMappingURL=types.js.map","import { CandidateType } from './types';\n/** enum type to simplify setting \"user-friendly\" notation if necessary */\nexport var NOTATION;\n(function (NOTATION) {\n NOTATION[\"FASTA\"] = \"fasta\";\n NOTATION[\"SEPARATOR\"] = \"separator\";\n NOTATION[\"HELM\"] = \"helm\";\n})(NOTATION || (NOTATION = {}));\nexport var ALPHABET;\n(function (ALPHABET) {\n ALPHABET[\"DNA\"] = \"DNA\";\n ALPHABET[\"RNA\"] = \"RNA\";\n ALPHABET[\"PT\"] = \"PT\";\n /** Unknown */\n ALPHABET[\"UN\"] = \"UN\";\n})(ALPHABET || (ALPHABET = {}));\nexport var TAGS;\n(function (TAGS) {\n TAGS[\"aligned\"] = \"aligned\";\n TAGS[\"alphabet\"] = \"alphabet\";\n TAGS[\"alphabetSize\"] = \".alphabetSize\";\n TAGS[\"alphabetIsMultichar\"] = \".alphabetIsMultichar\";\n TAGS[\"separator\"] = \"separator\";\n TAGS[\"isHelmCompatible\"] = \".isHelmCompatible\";\n TAGS[\"positionNames\"] = \".positionNames\";\n TAGS[\"positionLabels\"] = \".positionLabels\";\n TAGS[\"regions\"] = \".regions\";\n})(TAGS || (TAGS = {}));\nexport const positionSeparator = ', ';\nexport const monomerRe = /(?:\\[([A-Za-z0-9_\\-,()]+)\\])|([A-Za-z\\-])/g;\nexport const helmRe = /(PEPTIDE1|DNA1|RNA1)\\{([^}]+)}/g;\nexport const helmPp1Re = /\\[([^\\[\\]]+)]/g;\nexport const Alphabets = new class {\n constructor() {\n this.fasta = {\n peptide: new Set([\n 'G', 'L', 'Y', 'S', 'E', 'Q', 'D', 'N', 'F', 'A',\n 'K', 'R', 'H', 'C', 'V', 'P', 'W', 'I', 'M', 'T',\n ]),\n dna: new Set(['A', 'C', 'G', 'T']),\n rna: new Set(['A', 'C', 'G', 'U']),\n };\n }\n}();\nexport const candidateAlphabets = [\n new CandidateType(ALPHABET.PT, Alphabets.fasta.peptide, 0.50),\n new CandidateType(ALPHABET.DNA, Alphabets.fasta.dna, 0.55),\n new CandidateType(ALPHABET.RNA, Alphabets.fasta.rna, 0.55),\n];\n//# sourceMappingURL=consts.js.map","import { monomerWorksConsts as C } from './consts';\nimport { HELM_CORE_FIELDS, } from '../utils/const';\nimport { ALPHABET } from '../utils/macromolecule/consts';\n/** Get a mapping of peptide symbols to HELM monomer library objects with selected fields.\n * @param {IMonomerLib} monomerLib - Monomer library\n * @param {HELM_POLYMER_TYPE} polymerType - Polymer type\n * @param {ALPHABET} alphabet - Alphabet of the column\n * @return {Map<string, any>} - Mapping of peptide symbols to HELM monomer library objects with selected fields*/\nexport function getFormattedMonomerLib(monomerLib, polymerType, alphabet) {\n const map = new Map();\n for (const monomerSymbol of monomerLib.getMonomerSymbolsByType(polymerType)) {\n const it = monomerLib.getMonomer(polymerType, monomerSymbol);\n if (polymerType === \"RNA\" /* HELM_POLYMER_TYPE.RNA */ &&\n (it[\"monomerType\" /* HELM_FIELDS.MONOMER_TYPE */] === \"Branch\" /* HELM_MONOMER_TYPE.BRANCH */ ||\n alphabet === ALPHABET.DNA && it[\"symbol\" /* HELM_FIELDS.SYMBOL */] === C.DEOXYRIBOSE ||\n alphabet === ALPHABET.RNA && it[\"symbol\" /* HELM_FIELDS.SYMBOL */] === C.RIBOSE ||\n it[\"symbol\" /* HELM_FIELDS.SYMBOL */] === C.PHOSPHATE) ||\n polymerType === \"PEPTIDE\" /* HELM_POLYMER_TYPE.PEPTIDE */ &&\n it[\"monomerType\" /* HELM_FIELDS.MONOMER_TYPE */] !== \"Branch\" /* HELM_MONOMER_TYPE.BRANCH */) {\n const monomerObject = {};\n HELM_CORE_FIELDS.forEach((field) => {\n //@ts-ignore\n monomerObject[field] = it[field];\n });\n map.set(it[\"symbol\" /* HELM_FIELDS.SYMBOL */], monomerObject);\n }\n }\n return map;\n}\n/** Translate a sequence of monomer symbols into Molfile V3000\n * @param {string[]} monomerSeq - Sequence of monomer symbols\n * @param {Map<string, MolGraph>} monomersDict - Mapping of monomer symbols to MolGraph objects\n * @param {ALPHABET} alphabet - Alphabet of the column\n * @param {HELM_POLYMER_TYPE} polymerType - Polymer type\n * @return {string} - Molfile V3000*/\nexport function monomerSeqToMolfile(monomerSeq, monomersDict, alphabet, polymerType) {\n if (monomerSeq.length === 0) {\n // throw new Error('monomerSeq is empty');\n return '';\n }\n // define atom and bond counts, taking into account the bond type\n const getAtomAndBondCounts = getResultingAtomBondCounts;\n const { atomCount, bondCount } = getAtomAndBondCounts(monomerSeq, monomersDict, alphabet, polymerType);\n // create arrays to store lines of the resulting molfile\n const molfileAtomBlock = new Array(atomCount);\n const molfileBondBlock = new Array(bondCount);\n let addMonomerToMolblock; // todo: types?\n let sugar = null;\n let phosphate = null;\n if (polymerType === \"PEPTIDE\" /* HELM_POLYMER_TYPE.PEPTIDE */) {\n addMonomerToMolblock = addAminoAcidToMolblock;\n }\n else { // nucleotides\n addMonomerToMolblock = addNucleotideToMolblock;\n sugar = (alphabet === ALPHABET.DNA) ? monomersDict.get(C.DEOXYRIBOSE) : monomersDict.get(C.RIBOSE);\n phosphate = monomersDict.get(C.PHOSPHATE);\n }\n const v = {\n i: 0,\n nodeShift: 0,\n bondShift: 0,\n backbonePositionShift: new Array(2).fill(0),\n branchPositionShift: new Array(2).fill(0),\n backboneAttachNode: 0,\n branchAttachNode: 0,\n flipFactor: 1,\n };\n const LC = {\n sugar: sugar,\n phosphate: phosphate,\n seqLength: monomerSeq.length,\n atomCount: atomCount,\n bondCount: bondCount,\n };\n const steabsCollection = [];\n let nAtoms = 0;\n for (v.i = 0; v.i < LC.seqLength; ++v.i) {\n const monomer = monomersDict.get(monomerSeq[v.i]);\n addMonomerToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v, LC);\n //adding stereo atoms to array for further STEABS block generation\n monomer.stereoAtoms?.forEach((i) => steabsCollection.push(i + nAtoms));\n nAtoms += monomer.atoms.x.length;\n }\n capResultingMolblock(molfileAtomBlock, molfileBondBlock, v, LC);\n const molfileCountsLine = C.V3K_BEGIN_COUNTS_LINE + atomCount + ' ' + bondCount + C.V3K_COUNTS_LINE_ENDING;\n // todo: possible optimization may be achieved by replacing .join('') with +=\n // since counterintuitively joining an array into a new string is reportedly\n // slower than using += as below\n let result = '';\n result += C.V3K_HEADER_FIRST_LINE;\n result += C.V3K_HEADER_SECOND_LINE;\n result += C.V3K_BEGIN_CTAB_BLOCK;\n result += molfileCountsLine;\n result += C.V3K_BEGIN_ATOM_BLOCK;\n result += molfileAtomBlock.join('');\n result += C.V3K_END_ATOM_BLOCK;\n result += C.V3K_BEGIN_BOND_BLOCK;\n result += molfileBondBlock.join('');\n result += C.V3K_END_BOND_BLOCK;\n if (steabsCollection.length > 0)\n result += getCollectionBlock(steabsCollection);\n result += C.V3K_END_CTAB_BLOCK;\n result += C.V3K_END;\n // return molfileParts.join('');\n return result;\n}\nfunction getCollectionBlock(collection) {\n //one row in STEABS block can be no longer than 80 symbols\n //maxSymbols = 80 symbols minus ' -\\n' (4 symbols)\n const maxSymbols = 76;\n const rowsArray = [];\n let newCollectionRow = `M V30 MDLV30/STEABS ATOMS=(${collection.length}`;\n for (let i = 0; i < collection.length; i++) {\n const updatedRow = `${newCollectionRow} ${collection[i]}`;\n if (updatedRow.length > maxSymbols) {\n rowsArray.push(`${newCollectionRow} -\\n`);\n newCollectionRow = `M V30 ${collection[i]}`;\n }\n else\n newCollectionRow = updatedRow;\n //in case last atom was added - close the block\n if (i === collection.length - 1)\n rowsArray.push(`${newCollectionRow})\\n`);\n }\n return `M V30 BEGIN COLLECTION\\n${rowsArray.join('')}M V30 END COLLECTION\\n`;\n}\n/** Cap the resulting (after sewing up all the monomers) molfile with 'O'\n * @param {string[]} molfileAtomBlock - Array of lines of the resulting molfile atom block\n * @param {string[]} molfileBondBlock - Array of lines of the resulting molfile bond block\n * @param {LoopVariables} v - Loop variables\n * @param {LoopConstants} LC - Loop constants*/\nfunction capResultingMolblock(molfileAtomBlock, molfileBondBlock, v, LC) {\n // add terminal oxygen\n const atomIdx = v.nodeShift + 1;\n molfileAtomBlock[LC.atomCount] = C.V3K_BEGIN_DATA_LINE + atomIdx + ' ' +\n C.OXYGEN + ' ' + keepPrecision(v.backbonePositionShift[0]) + ' ' +\n v.flipFactor * keepPrecision(v.backbonePositionShift[1]) + ' ' + '0.000000 0' + '\\n';\n // add terminal bond\n const firstAtom = v.backboneAttachNode;\n const secondAtom = atomIdx;\n molfileBondBlock[LC.bondCount] = C.V3K_BEGIN_DATA_LINE + v.bondShift + ' ' +\n 1 + ' ' + firstAtom + ' ' + secondAtom + '\\n';\n}\nfunction addAminoAcidToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v) {\n v.flipFactor = (-1) ** (v.i % 2); // to flip every even monomer over OX\n addBackboneMonomerToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v);\n}\nfunction addBackboneMonomerToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v) {\n // todo: remove these comments to the docstrings of the corr. functions\n // construnct the lines of V3K molfile atom block\n fillAtomLines(monomer, molfileAtomBlock, v);\n // construct the lines of V3K molfile bond block\n fillBondLines(monomer, molfileBondBlock, v);\n // peptide bond\n fillChainExtendingBond(monomer, molfileBondBlock, v);\n // update branch variables if necessary\n if (monomer.meta.branchShift !== null && monomer.meta.terminalNodes.length > 2)\n updateBranchVariables(monomer, v);\n // update loop variables\n updateChainExtendingVariables(monomer, v);\n}\nfunction addNucleotideToMolblock(nucleobase, molfileAtomBlock, molfileBondBlock, v, LC) {\n // construnct the lines of V3K molfile atom block corresponding to phosphate\n // and sugar\n if (v.i === 0) {\n addBackboneMonomerToMolblock(LC.sugar, molfileAtomBlock, molfileBondBlock, v);\n }\n else {\n for (const monomer of [LC.phosphate, LC.sugar])\n addBackboneMonomerToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v);\n }\n addBranchMonomerToMolblock(nucleobase, molfileAtomBlock, molfileBondBlock, v);\n}\nfunction addBranchMonomerToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v) {\n fillBranchAtomLines(monomer, molfileAtomBlock, v);\n fillBondLines(monomer, molfileBondBlock, v);\n fillBackboneToBranchBond(monomer, molfileBondBlock, v);\n // C-N bond\n const bondIdx = v.bondShift;\n const firstAtom = v.branchAttachNode;\n const secondAtom = monomer.meta.terminalNodes[0] + v.nodeShift;\n molfileBondBlock[bondIdx - 1] = C.V3K_BEGIN_DATA_LINE + bondIdx + ' ' +\n 1 + ' ' + firstAtom + ' ' + secondAtom + '\\n';\n // update loop variables\n v.bondShift += monomer.bonds.atomPairs.length + 1;\n v.nodeShift += monomer.atoms.atomTypes.length;\n}\nfunction updateChainExtendingVariables(monomer, v) {\n v.backboneAttachNode = v.nodeShift + monomer.meta.terminalNodes[1];\n v.bondShift += monomer.bonds.atomPairs.length + 1;\n v.nodeShift += monomer.atoms.atomTypes.length;\n v.backbonePositionShift[0] += monomer.meta.backboneShift[0]; // todo: non-null check\n v.backbonePositionShift[1] += v.flipFactor * monomer.meta.backboneShift[1];\n}\nfunction updateBranchVariables(monomer, v) {\n v.branchAttachNode = v.nodeShift + monomer.meta.terminalNodes[2];\n for (let i = 0; i < 2; ++i)\n v.branchPositionShift[i] = v.backbonePositionShift[i] + monomer.meta.branchShift[i];\n}\nfunction fillAtomLines(monomer, molfileAtomBlock, v) {\n for (let j = 0; j < monomer.atoms.atomTypes.length; ++j) {\n const atomIdx = v.nodeShift + j + 1;\n molfileAtomBlock[v.nodeShift + j] = C.V3K_BEGIN_DATA_LINE + atomIdx + ' ' +\n monomer.atoms.atomTypes[j] + ' ' +\n keepPrecision(v.backbonePositionShift[0] + monomer.atoms.x[j]) + ' ' +\n keepPrecision(v.backbonePositionShift[1] + v.flipFactor * monomer.atoms.y[j]) +\n ' ' + monomer.atoms.kwargs[j];\n }\n}\n// todo: remove as quickfix\nfunction fillBranchAtomLines(monomer, molfileAtomBlock, v) {\n for (let j = 0; j < monomer.atoms.atomTypes.length; ++j) {\n const atomIdx = v.nodeShift + j + 1;\n molfileAtomBlock[v.nodeShift + j] = C.V3K_BEGIN_DATA_LINE + atomIdx + ' ' +\n monomer.atoms.atomTypes[j] + ' ' +\n keepPrecision(v.branchPositionShift[0] + monomer.atoms.x[j]) + ' ' +\n keepPrecision(v.branchPositionShift[1] + v.flipFactor * monomer.atoms.y[j]) +\n ' ' + monomer.atoms.kwargs[j];\n }\n}\nfunction fillBondLines(monomer, molfileBondBlock, v) {\n // construct the lines of V3K molfile bond block\n for (let j = 0; j < monomer.bonds.atomPairs.length; ++j) {\n const bondIdx = v.bondShift + j + 1;\n const firstAtom = monomer.bonds.atomPairs[j][0] + v.nodeShift;\n const secondAtom = monomer.bonds.atomPairs[j][1] + v.nodeShift;\n let bondCfg = '';\n if (monomer.bonds.bondConfiguration.has(j)) {\n // flip orientation when necessary\n let orientation = monomer.bonds.bondConfiguration.get(j);\n if (v.flipFactor < 0)\n orientation = (orientation === 1) ? 3 : 1;\n bondCfg = ' CFG=' + orientation;\n }\n const kwargs = monomer.bonds.kwargs.has(j) ?\n ' ' + monomer.bonds.kwargs.get(j) : '';\n molfileBondBlock[v.bondShift + j] = C.V3K_BEGIN_DATA_LINE + bondIdx + ' ' +\n monomer.bonds.bondTypes[j] + ' ' +\n firstAtom + ' ' + secondAtom + bondCfg + kwargs + '\\n';\n }\n}\nfunction fillChainExtendingBond(monomer, molfileBondBlock, v) {\n if (v.backboneAttachNode !== 0) {\n const bondIdx = v.bondShift;\n const firstAtom = v.backboneAttachNode;\n const secondAtom = monomer.meta.terminalNodes[0] + v.nodeShift;\n molfileBondBlock[v.bondShift - 1] = C.V3K_BEGIN_DATA_LINE + bondIdx + ' ' +\n 1 + ' ' + firstAtom + ' ' + secondAtom + '\\n';\n }\n}\n// todo: remove\nfunction fillBackboneToBranchBond(branchMonomer, molfileBondBlock, v) {\n const bondIdx = v.bondShift;\n const firstAtom = v.branchAttachNode;\n const secondAtom = branchMonomer.meta.terminalNodes[0] + v.nodeShift;\n molfileBondBlock[bondIdx - 1] = C.V3K_BEGIN_DATA_LINE + bondIdx + ' ' +\n 1 + ' ' + firstAtom + ' ' + secondAtom + '\\n';\n}\n/** Compute the atom/bond counts for the resulting molfile, depending on the\n * type of polymer (peptide/nucleotide)\n * @param {string[]}monomerSeq - the sequence of monomers\n * @param {Map<string, MolGraph>}monomersDict - the dictionary of monomers\n * @param {ALPHABET}alphabet - the alphabet of the monomers\n * @param {HELM_POLYMER_TYPE}polymerType - the type of polymer\n * @return {{atomCount: number, bondCount: number}} - the atom/bond counts*/\nfunction getResultingAtomBondCounts(monomerSeq, monomersDict, alphabet, polymerType) {\n let atomCount = 0;\n let bondCount = 0;\n // sum up all the atoms/nodes provided by the sequence\n for (const monomerSymbol of monomerSeq) {\n if (monomerSymbol === '')\n continue; // Skip for gap/empty monomer in MSA\n const monomer = monomersDict.get(monomerSymbol);\n atomCount += monomer.atoms.x.length;\n bondCount += monomer.bonds.bondTypes.length;\n }\n // add extra values depending on the polymer type\n if (polymerType === \"PEPTIDE\" /* HELM_POLYMER_TYPE.PEPTIDE */) {\n // add the rightmost/terminating cap group 'OH' (i.e. 'O')\n atomCount += 1;\n // add chain-extending bonds (C-NH per each monomer pair and terminal C-OH)\n bondCount += monomerSeq.length;\n }\n else { // nucleotides\n const sugar = (alphabet === ALPHABET.DNA) ?\n monomersDict.get(C.DEOXYRIBOSE) : monomersDict.get(C.RIBOSE);\n const phosphate = monomersDict.get(C.PHOSPHATE);\n // add phosphate per each pair of nucleobase symbols\n atomCount += (monomerSeq.length - 1) * phosphate.atoms.x.length;\n // add sugar per each nucleobase symbol\n atomCount += monomerSeq.length * sugar.atoms.x.length;\n // add the leftmost cap group 'OH' (i.e. 'O')\n atomCount += 1;\n // add bonds from phosphate monomers\n bondCount += (monomerSeq.length - 1) * phosphate.bonds.bondTypes.length;\n // add bonds from sugar monomers\n bondCount += monomerSeq.length * sugar.bonds.bondTypes.length;\n // exclude the first chain-extending bond O-P (absent, no 'leftmost' phosphate)\n bondCount -= 1;\n // add chain-extending and branch bonds (O-P, C-O and C-N per each nucleotide)\n bondCount += monomerSeq.length * 3;\n }\n return { atomCount, bondCount };\n}\n/** Keep precision upon floating point operations over atom coordinates\n * @param {number}x - the floating point number\n * @return {number} - the floating point number with the same precision\n*/\nexport function keepPrecision(x) {\n return Math.round(C.PRECISION_FACTOR * x) / C.PRECISION_FACTOR;\n}\n//# sourceMappingURL=to-atomic-level-utils.js.map","import { monomerSeqToMolfile } from './to-atomic-level-utils';\nonmessage = (event) => {\n const { monomerSequencesArray, monomersDict, alphabet, polymerType, start, end } = event.data;\n const molfileList = new Array(end - start);\n const molfileWarningList = new Array(0);\n for (let rowI = start; rowI < end; ++rowI) {\n try {\n const monomerSeq = monomerSequencesArray[rowI];\n molfileList[rowI - start] = monomerSeqToMolfile(monomerSeq, monomersDict, alphabet, polymerType);\n }\n catch (err) {\n const errMsg = err instanceof Error ? err.message : err.toString();\n const msg = `Cannot get molfile of row #${rowI}: ${errMsg}.`;\n molfileWarningList.push(msg);\n }\n }\n postMessage({ molfileList, molfileWarningList });\n};\n//# sourceMappingURL=seq-to-molfile-worker.js.map"],"names":["monomerWorksConsts","V2K_RGP_SHIFT","V2K_RGP_LINE","V2K_A_LINE","V3K_COUNTS_SHIFT","V3K_IDX_SHIFT","V3K_HEADER_FIRST_LINE","V3K_HEADER_SECOND_LINE","V3K_BEGIN_CTAB_BLOCK","V3K_END_CTAB_BLOCK","V3K_BEGIN_COUNTS_LINE","V3K_COUNTS_LINE_ENDING","V3K_BEGIN_ATOM_BLOCK","V3K_END_ATOM_BLOCK","V3K_BEGIN_BOND_BLOCK","V3K_END_BOND_BLOCK","V3K_BOND_CONFIG","V3K_BEGIN_DATA_LINE","V3K_END","PRECISION_FACTOR","DEOXYRIBOSE","RIBOSE","PHOSPHATE","OXYGEN","HYDROGEN","RegExp","CandidateType","constructor","name","alphabet","cutoff","this","NOTATION","TAGS","ALPHABET","Alphabets","fasta","peptide","Set","dna","rna","monomerSeqToMolfile","monomerSeq","monomersDict","polymerType","length","getAtomAndBondCounts","getResultingAtomBondCounts","atomCount","bondCount","molfileAtomBlock","Array","molfileBondBlock","addMonomerToMolblock","sugar","phosphate","addAminoAcidToMolblock","addNucleotideToMolblock","DNA","get","v","i","nodeShift","bondShift","backbonePositionShift","fill","branchPositionShift","backboneAttachNode","branchAttachNode","flipFactor","LC","seqLength","steabsCollection","nAtoms","monomer","stereoAtoms","forEach","push","atoms","x","atomIdx","keepPrecision","firstAtom","secondAtom","capResultingMolblock","molfileCountsLine","result","join","collection","rowsArray","newCollectionRow","updatedRow","getCollectionBlock","addBackboneMonomerToMolblock","j","atomTypes","y","kwargs","fillAtomLines","fillBondLines","bondIdx","meta","terminalNodes","fillChainExtendingBond","branchShift","updateBranchVariables","bonds","atomPairs","backboneShift","updateChainExtendingVariables","nucleobase","fillBranchAtomLines","branchMonomer","fillBackboneToBranchBond","addBranchMonomerToMolblock","bondCfg","bondConfiguration","has","orientation","bondTypes","monomerSymbol","Math","round","PT","RNA","onmessage","event","monomerSequencesArray","start","end","data","molfileList","molfileWarningList","rowI","err","msg","Error","message","toString","postMessage"],"sourceRoot":""}
@@ -1,31 +0,0 @@
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
- export const rendererSettingsChangedState = {
6
- true: '1',
7
- false: '0',
8
- };
9
-
10
- export const enum Temps {
11
- maxMonomerLength = '.mm.cellRenderer.maxMonomerLength',
12
- colorCode = '.mm.cellRenderer.colorCode',
13
- compareWithCurrent = '.mm.cellRenderer.compareWithCurrent',
14
- highlightDifference = '.mm.cellRenderer.highlightDifference',
15
- gapLength = '.mm.cellRenderer.gapLength',
16
- monomerPlacer = '.mm.cellRenderer.monomerPlacer',
17
-
18
- rendererSettingsChanged = '.mm.cellRenderer.settingsChanged',
19
- }
20
-
21
- export const enum tempTAGS {
22
- referenceSequence = 'reference-sequence',
23
- currentWord = 'current-word',
24
- }
25
-
26
- // export const MacromoleculeCellRendererDefaults = new class {
27
- // monomerWidth: MonomerWidthMode = MonomerWidthMode.short;
28
- // maxMonomerLength: number = 3;
29
- // colorCode: boolean = true;
30
- // compareWithCurrent: boolean = true;
31
- // }();