@datagrok/sequence-translator 1.9.6 → 1.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/package.js CHANGED
@@ -1132,11 +1132,13 @@ function monomerSeqToMolfile(monomerSeq, monomersDict, alphabet, polymerType) {
1132
1132
  const monomers = new _types__WEBPACK_IMPORTED_MODULE_1__.MonomerMap();
1133
1133
  const steabsCollection = [];
1134
1134
  let nAtoms = 0;
1135
+ let lastMonomerCappingAtom = undefined;
1135
1136
  for (v.i = 0; v.i < LC.seqLength; ++v.i) {
1136
1137
  const seqMonomer = monomerSeq[v.i];
1137
1138
  if (seqMonomer.symbol === _utils_macromolecule_consts__WEBPACK_IMPORTED_MODULE_3__.GAP_SYMBOL)
1138
1139
  continue;
1139
1140
  const monomer = (0,_types__WEBPACK_IMPORTED_MODULE_1__.getMolGraph)(monomersDict, { symbol: seqMonomer.symbol, polymerType: (0,_monomer_works__WEBPACK_IMPORTED_MODULE_4__.helmTypeToPolymerType)(seqMonomer.biotype) });
1141
+ lastMonomerCappingAtom = monomer.terminalR2Atom;
1140
1142
  const mAtomFirst = v.nodeShift;
1141
1143
  const mBondFirst = v.bondShift;
1142
1144
  addMonomerToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v, LC);
@@ -1159,7 +1161,7 @@ function monomerSeqToMolfile(monomerSeq, monomersDict, alphabet, polymerType) {
1159
1161
  }
1160
1162
  // if the last monomer needs to be capped, add the terminal OH to the resulting molfile
1161
1163
  if (needsCapping)
1162
- capResultingMolblock(molfileAtomBlock, molfileBondBlock, v, LC);
1164
+ capResultingMolblock(molfileAtomBlock, molfileBondBlock, v, LC, lastMonomerCappingAtom ?? _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.OXYGEN);
1163
1165
  const molfileCountsLine = _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.V3K_BEGIN_COUNTS_LINE + atomCount + ' ' + bondCount + _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.V3K_COUNTS_LINE_ENDING;
1164
1166
  // todo: possible optimization may be achieved by replacing .join('') with +=
1165
1167
  // since counterintuitively joining an array into a new string is reportedly
@@ -1207,11 +1209,11 @@ function getCollectionBlock(collection) {
1207
1209
  * @param {string[]} molfileBondBlock - Array of lines of the resulting molfile bond block
1208
1210
  * @param {LoopVariables} v - Loop variables
1209
1211
  * @param {LoopConstants} LC - Loop constants*/
1210
- function capResultingMolblock(molfileAtomBlock, molfileBondBlock, v, LC) {
1212
+ function capResultingMolblock(molfileAtomBlock, molfileBondBlock, v, LC, cappingAtomType = _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.OXYGEN) {
1211
1213
  // add terminal oxygen
1212
1214
  const atomIdx = v.nodeShift + 1;
1213
1215
  molfileAtomBlock[LC.atomCount] = _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.V3K_BEGIN_DATA_LINE + atomIdx + ' ' +
1214
- _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.OXYGEN + ' ' + keepPrecision(v.backbonePositionShift[0]) + ' ' +
1216
+ (cappingAtomType ?? _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.OXYGEN) + ' ' + keepPrecision(v.backbonePositionShift[0]) + ' ' +
1215
1217
  v.flipFactor * keepPrecision(v.backbonePositionShift[1]) + ' ' + '0.000000 0' + '\n';
1216
1218
  // add terminal bond
1217
1219
  const firstAtom = v.backboneAttachNode;
@@ -1364,8 +1366,10 @@ function getResultingAtomBondCounts(monomerSeq, monomersDict, alphabet, polymerT
1364
1366
  // add chain-extending bonds (C-NH per each monomer pair and terminal C-OH)
1365
1367
  bondCount += monomerCount;
1366
1368
  // if the last monomer is something like NH2, which only has R1, there is no need to cap it
1369
+ // although, this should never happen, but hey... in other bits of code, there is a chunk that adds pseudo-R2 as hydrogen
1370
+ // we should also check, if the R2 of the last monomer is not hydrogen, that case should also be omitted
1367
1371
  if (monomerCount > 0) {
1368
- if ((lastMonomerGraph?.meta?.rNodes?.length ?? 0) < 2) {
1372
+ if ((lastMonomerGraph?.meta?.rNodes?.length ?? 0) < 2 || lastMonomerGraph?.terminalR2Atom?.toLowerCase() === _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.HYDROGEN.toLowerCase()) {
1369
1373
  needsCapping = false;
1370
1374
  atomCount -= 1; // remove the last atom (the terminal 'O')
1371
1375
  bondCount -= 1; // remove the last bond (the terminal C-OH)
@@ -1644,7 +1648,9 @@ function setShiftsAndTerminalNodes(polymerType, monomerGraph, monomerSymbol) {
1644
1648
  // remove the 'rightmost' chain-extending r-group node in the backbone
1645
1649
  if (polymerType === "PEPTIDE" /* HELM_POLYMER_TYPE.PEPTIDE */) {
1646
1650
  setShifts(monomerGraph, polymerType);
1647
- removeNodeAndBonds(monomerGraph, monomerGraph.meta.rNodes[1]);
1651
+ const removedR2Atom = removeNodeAndBonds(monomerGraph, monomerGraph.meta.rNodes[1]);
1652
+ if (removedR2Atom?.removedAtom)
1653
+ monomerGraph.terminalR2Atom = removedR2Atom.removedAtom; // store the removed R2 Atom type, if any
1648
1654
  }
1649
1655
  else { // nucleotides
1650
1656
  if (monomerSymbol === _consts__WEBPACK_IMPORTED_MODULE_9__.monomerWorksConsts.RIBOSE.symbol || monomerSymbol === _consts__WEBPACK_IMPORTED_MODULE_9__.monomerWorksConsts.DEOXYRIBOSE.symbol) {
@@ -1695,14 +1701,30 @@ function getMonomerMetadata(atoms, bonds, capGroups, capGroupIdxMap) {
1695
1701
  const existingRgroupIdx = Array.from(capGroupIdxMap.keys()).find((i) => capGroupIdxMap.get(i) === existingRgroup) - 1; // -1 because molfile indexing starts from 1
1696
1702
  const existingRgroupX = atoms.x[existingRgroupIdx];
1697
1703
  const existingRgroupY = atoms.y[existingRgroupIdx];
1698
- const furthestAtomIdx = atoms.x.reduce((furthestIdx, x, idx) => {
1704
+ const atomBondedToExistingRgroupIdx = bonds.atomPairs.find((pair) => pair.includes(existingRgroupIdx + 1)).
1705
+ find((i) => i !== existingRgroupIdx + 1) - 1; // -1 because molfile indexing starts from 1
1706
+ let furthestAtomIdx = atoms.x.reduce((furthestIdx, x, idx) => {
1699
1707
  if (idx === existingRgroupIdx)
1700
1708
  return furthestIdx; // skip existing r-group
1709
+ // also skip the atom bonded to the existing r-group
1710
+ if (idx === atomBondedToExistingRgroupIdx)
1711
+ return furthestIdx;
1701
1712
  const y = atoms.y[idx];
1702
1713
  const dist = Math.sqrt((x - existingRgroupX) ** 2 + (y - existingRgroupY) ** 2);
1703
1714
  return dist > Math.sqrt((atoms.x[furthestIdx] - existingRgroupX) ** 2 +
1704
1715
  (atoms.y[furthestIdx] - existingRgroupY) ** 2) ? idx : furthestIdx;
1705
- }, 0);
1716
+ }, -1);
1717
+ if (furthestAtomIdx === -1) {
1718
+ furthestAtomIdx = atoms.x.length;
1719
+ // add pseudo-hydrogen atom, very relevant for stuff like NH2-R
1720
+ atoms.x = new Float32Array([...atoms.x, -existingRgroupX]);
1721
+ atoms.y = new Float32Array([...atoms.y, -existingRgroupY]);
1722
+ atoms.atomTypes = [...atoms.atomTypes, 'H'];
1723
+ atoms.kwargs = [...atoms.kwargs, ''];
1724
+ bonds.atomPairs.push([atomBondedToExistingRgroupIdx + 1, furthestAtomIdx + 1]); // +1 because molfile indexing starts from 1
1725
+ bonds.bondTypes = new Uint32Array([...bonds.bondTypes, 1]); // single bond
1726
+ bonds.kwargs.set(bonds.atomPairs.length - 1, ''); // empty kwargs for the new bond
1727
+ }
1706
1728
  capGroupIdxMap.set(furthestAtomIdx + 1, missingRGroup); // +1 because molfile indexing starts from 1
1707
1729
  // finaly splice the capGroups array in correct place
1708
1730
  if (missingRGroup === 1)
@@ -2049,7 +2071,9 @@ function removeRgroupKwargs(monomerGraph) {
2049
2071
  /** Remove node 'removedNode' and the associated bonds. Notice, numeration of
2050
2072
  * nodes in molfiles starts from 1, not 0
2051
2073
  * @param {MolGraph} monomerGraph - monomer graph
2052
- * @param {number} removedNode - node to be removed*/
2074
+ * @param {number} removedNode - node to be removed
2075
+ * @return {{removedAtom: string} | undefined} - removed atom type, if any
2076
+ * */
2053
2077
  function removeNodeAndBonds(monomerGraph, removedNode) {
2054
2078
  if (typeof removedNode !== 'undefined') {
2055
2079
  const removedNodeIdx = removedNode - 1;
@@ -2057,7 +2081,7 @@ function removeNodeAndBonds(monomerGraph, removedNode) {
2057
2081
  const bonds = monomerGraph.bonds;
2058
2082
  const meta = monomerGraph.meta;
2059
2083
  // remove the node from atoms
2060
- atoms.atomTypes.splice(removedNodeIdx, 1);
2084
+ const removedAtomType = atoms.atomTypes.splice(removedNodeIdx, 1)[0];
2061
2085
  atoms.x = spliceTypedArray(Float32Array, atoms.x, removedNodeIdx, 1);
2062
2086
  atoms.y = spliceTypedArray(Float32Array, atoms.y, removedNodeIdx, 1);
2063
2087
  atoms.kwargs.splice(removedNodeIdx, 1);
@@ -2111,6 +2135,7 @@ function removeNodeAndBonds(monomerGraph, removedNode) {
2111
2135
  bonds.kwargs.set(key - 1, value);
2112
2136
  }
2113
2137
  });
2138
+ return removedAtomType ? { removedAtom: removedAtomType } : undefined;
2114
2139
  }
2115
2140
  }
2116
2141
  // todo: rewrite the following two functions using templates,
@@ -3183,6 +3208,15 @@ class MonomerPlacer extends _cell_renderer_back_base__WEBPACK_IMPORTED_MODULE_5_
3183
3208
  return renderMultiline === 'true';
3184
3209
  }
3185
3210
  calculateMultiLineLayoutDynamic(g, w, h, subParts, positionShift, maxLengthOfMonomer) {
3211
+ if (this.dirty) {
3212
+ try {
3213
+ this.reset();
3214
+ }
3215
+ catch (err) {
3216
+ const [errMsg, errStack] = (0,_err_info__WEBPACK_IMPORTED_MODULE_7__.errInfo)(err);
3217
+ this.logger.error(errMsg, undefined, errStack);
3218
+ }
3219
+ }
3186
3220
  // --- 1. Setup ---
3187
3221
  const { lineHeight, monomerSpacing } = this.calculateFontBasedSpacing(g);
3188
3222
  const availableWidth = w - (this.padding * 2);
@@ -3460,6 +3494,7 @@ class MonomerPlacer extends _cell_renderer_back_base__WEBPACK_IMPORTED_MODULE_5_
3460
3494
  this.setMonomerLengthLimit(maxLengthOfMonomer);
3461
3495
  this.setSeparatorWidth(sh.isMsa() ? msaGapLength : gapLength);
3462
3496
  tableCol.temp[".mm.cellRenderer.settingsChanged" /* MmcrTemps.rendererSettingsChanged */] = _cell_renderer_consts__WEBPACK_IMPORTED_MODULE_9__.rendererSettingsChangedState.false;
3497
+ this.dirty = true;
3463
3498
  }
3464
3499
  const rowIdx = gridCell.cell.rowIndex;
3465
3500
  const value = gridCell.cell.value;
@@ -3486,7 +3521,7 @@ class MonomerPlacer extends _cell_renderer_back_base__WEBPACK_IMPORTED_MODULE_5_
3486
3521
  return wu__WEBPACK_IMPORTED_MODULE_2___default().count(0).take(seqSS.length).slice(positionShift).map((posIdx) => seqSS.getCanonical(posIdx)).toArray();
3487
3522
  })();
3488
3523
  const selectedPosition = Number.parseInt(tableCol.getTag(_macromolecule__WEBPACK_IMPORTED_MODULE_4__.TAGS.selectedPosition) ?? '-200');
3489
- const shouldUseMultiLine = this.shouldUseMultilineRendering(tableCol) && drawStyle !== _cell_renderer__WEBPACK_IMPORTED_MODULE_8__.DrawStyle.MSA;
3524
+ const shouldUseMultiLine = this.shouldUseMultilineRendering(tableCol);
3490
3525
  if (shouldUseMultiLine) {
3491
3526
  const currentCellBounds = [];
3492
3527
  const layout = this.calculateMultiLineLayoutDynamic(g, w, h, subParts, positionShift, maxLengthOfMonomer);
@@ -3981,6 +4016,7 @@ __webpack_require__.r(__webpack_exports__);
3981
4016
  /* harmony export */ BioTags: () => (/* binding */ TAGS),
3982
4017
  /* harmony export */ GAP_SYMBOL: () => (/* binding */ GAP_SYMBOL),
3983
4018
  /* harmony export */ GapOriginals: () => (/* binding */ GapOriginals),
4019
+ /* harmony export */ MONOMER_MOTIF_SPLITTER: () => (/* binding */ MONOMER_MOTIF_SPLITTER),
3984
4020
  /* harmony export */ NOTATION: () => (/* binding */ NOTATION),
3985
4021
  /* harmony export */ TAGS: () => (/* binding */ TAGS),
3986
4022
  /* harmony export */ candidateAlphabets: () => (/* binding */ candidateAlphabets),
@@ -4050,6 +4086,7 @@ const GapOriginals = {
4050
4086
  [NOTATION.SEPARATOR]: '',
4051
4087
  [NOTATION.HELM]: '*',
4052
4088
  };
4089
+ const MONOMER_MOTIF_SPLITTER = ' , ';
4053
4090
  //# sourceMappingURL=consts.js.map
4054
4091
 
4055
4092
  /***/ }),
@@ -4064,6 +4101,7 @@ const GapOriginals = {
4064
4101
  __webpack_require__.r(__webpack_exports__);
4065
4102
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
4066
4103
  /* harmony export */ ALPHABET: () => (/* reexport safe */ _consts__WEBPACK_IMPORTED_MODULE_0__.ALPHABET),
4104
+ /* harmony export */ MONOMER_MOTIF_SPLITTER: () => (/* reexport safe */ _consts__WEBPACK_IMPORTED_MODULE_0__.MONOMER_MOTIF_SPLITTER),
4067
4105
  /* harmony export */ NOTATION: () => (/* reexport safe */ _consts__WEBPACK_IMPORTED_MODULE_0__.NOTATION),
4068
4106
  /* harmony export */ TAGS: () => (/* reexport safe */ _consts__WEBPACK_IMPORTED_MODULE_0__.TAGS),
4069
4107
  /* harmony export */ candidateAlphabets: () => (/* reexport safe */ _consts__WEBPACK_IMPORTED_MODULE_0__.candidateAlphabets),
@@ -4082,6 +4120,7 @@ __webpack_require__.r(__webpack_exports__);
4082
4120
  /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ "./node_modules/@datagrok-libraries/bio/src/utils/macromolecule/utils.js");
4083
4121
 
4084
4122
 
4123
+
4085
4124
  //# sourceMappingURL=index.js.map
4086
4125
 
4087
4126
  /***/ }),