@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.
@@ -1179,11 +1179,13 @@ function monomerSeqToMolfile(monomerSeq, monomersDict, alphabet, polymerType) {
1179
1179
  const monomers = new _types__WEBPACK_IMPORTED_MODULE_1__.MonomerMap();
1180
1180
  const steabsCollection = [];
1181
1181
  let nAtoms = 0;
1182
+ let lastMonomerCappingAtom = undefined;
1182
1183
  for (v.i = 0; v.i < LC.seqLength; ++v.i) {
1183
1184
  const seqMonomer = monomerSeq[v.i];
1184
1185
  if (seqMonomer.symbol === _utils_macromolecule_consts__WEBPACK_IMPORTED_MODULE_3__.GAP_SYMBOL)
1185
1186
  continue;
1186
1187
  const monomer = (0,_types__WEBPACK_IMPORTED_MODULE_1__.getMolGraph)(monomersDict, { symbol: seqMonomer.symbol, polymerType: (0,_monomer_works__WEBPACK_IMPORTED_MODULE_4__.helmTypeToPolymerType)(seqMonomer.biotype) });
1188
+ lastMonomerCappingAtom = monomer.terminalR2Atom;
1187
1189
  const mAtomFirst = v.nodeShift;
1188
1190
  const mBondFirst = v.bondShift;
1189
1191
  addMonomerToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v, LC);
@@ -1206,7 +1208,7 @@ function monomerSeqToMolfile(monomerSeq, monomersDict, alphabet, polymerType) {
1206
1208
  }
1207
1209
  // if the last monomer needs to be capped, add the terminal OH to the resulting molfile
1208
1210
  if (needsCapping)
1209
- capResultingMolblock(molfileAtomBlock, molfileBondBlock, v, LC);
1211
+ capResultingMolblock(molfileAtomBlock, molfileBondBlock, v, LC, lastMonomerCappingAtom ?? _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.OXYGEN);
1210
1212
  const molfileCountsLine = _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.V3K_BEGIN_COUNTS_LINE + atomCount + ' ' + bondCount + _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.V3K_COUNTS_LINE_ENDING;
1211
1213
  // todo: possible optimization may be achieved by replacing .join('') with +=
1212
1214
  // since counterintuitively joining an array into a new string is reportedly
@@ -1254,11 +1256,11 @@ function getCollectionBlock(collection) {
1254
1256
  * @param {string[]} molfileBondBlock - Array of lines of the resulting molfile bond block
1255
1257
  * @param {LoopVariables} v - Loop variables
1256
1258
  * @param {LoopConstants} LC - Loop constants*/
1257
- function capResultingMolblock(molfileAtomBlock, molfileBondBlock, v, LC) {
1259
+ function capResultingMolblock(molfileAtomBlock, molfileBondBlock, v, LC, cappingAtomType = _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.OXYGEN) {
1258
1260
  // add terminal oxygen
1259
1261
  const atomIdx = v.nodeShift + 1;
1260
1262
  molfileAtomBlock[LC.atomCount] = _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.V3K_BEGIN_DATA_LINE + atomIdx + ' ' +
1261
- _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.OXYGEN + ' ' + keepPrecision(v.backbonePositionShift[0]) + ' ' +
1263
+ (cappingAtomType ?? _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.OXYGEN) + ' ' + keepPrecision(v.backbonePositionShift[0]) + ' ' +
1262
1264
  v.flipFactor * keepPrecision(v.backbonePositionShift[1]) + ' ' + '0.000000 0' + '\n';
1263
1265
  // add terminal bond
1264
1266
  const firstAtom = v.backboneAttachNode;
@@ -1411,8 +1413,10 @@ function getResultingAtomBondCounts(monomerSeq, monomersDict, alphabet, polymerT
1411
1413
  // add chain-extending bonds (C-NH per each monomer pair and terminal C-OH)
1412
1414
  bondCount += monomerCount;
1413
1415
  // if the last monomer is something like NH2, which only has R1, there is no need to cap it
1416
+ // although, this should never happen, but hey... in other bits of code, there is a chunk that adds pseudo-R2 as hydrogen
1417
+ // we should also check, if the R2 of the last monomer is not hydrogen, that case should also be omitted
1414
1418
  if (monomerCount > 0) {
1415
- if ((lastMonomerGraph?.meta?.rNodes?.length ?? 0) < 2) {
1419
+ if ((lastMonomerGraph?.meta?.rNodes?.length ?? 0) < 2 || lastMonomerGraph?.terminalR2Atom?.toLowerCase() === _consts__WEBPACK_IMPORTED_MODULE_0__.monomerWorksConsts.HYDROGEN.toLowerCase()) {
1416
1420
  needsCapping = false;
1417
1421
  atomCount -= 1; // remove the last atom (the terminal 'O')
1418
1422
  bondCount -= 1; // remove the last bond (the terminal C-OH)
@@ -1691,7 +1695,9 @@ function setShiftsAndTerminalNodes(polymerType, monomerGraph, monomerSymbol) {
1691
1695
  // remove the 'rightmost' chain-extending r-group node in the backbone
1692
1696
  if (polymerType === "PEPTIDE" /* HELM_POLYMER_TYPE.PEPTIDE */) {
1693
1697
  setShifts(monomerGraph, polymerType);
1694
- removeNodeAndBonds(monomerGraph, monomerGraph.meta.rNodes[1]);
1698
+ const removedR2Atom = removeNodeAndBonds(monomerGraph, monomerGraph.meta.rNodes[1]);
1699
+ if (removedR2Atom?.removedAtom)
1700
+ monomerGraph.terminalR2Atom = removedR2Atom.removedAtom; // store the removed R2 Atom type, if any
1695
1701
  }
1696
1702
  else { // nucleotides
1697
1703
  if (monomerSymbol === _consts__WEBPACK_IMPORTED_MODULE_9__.monomerWorksConsts.RIBOSE.symbol || monomerSymbol === _consts__WEBPACK_IMPORTED_MODULE_9__.monomerWorksConsts.DEOXYRIBOSE.symbol) {
@@ -1742,14 +1748,30 @@ function getMonomerMetadata(atoms, bonds, capGroups, capGroupIdxMap) {
1742
1748
  const existingRgroupIdx = Array.from(capGroupIdxMap.keys()).find((i) => capGroupIdxMap.get(i) === existingRgroup) - 1; // -1 because molfile indexing starts from 1
1743
1749
  const existingRgroupX = atoms.x[existingRgroupIdx];
1744
1750
  const existingRgroupY = atoms.y[existingRgroupIdx];
1745
- const furthestAtomIdx = atoms.x.reduce((furthestIdx, x, idx) => {
1751
+ const atomBondedToExistingRgroupIdx = bonds.atomPairs.find((pair) => pair.includes(existingRgroupIdx + 1)).
1752
+ find((i) => i !== existingRgroupIdx + 1) - 1; // -1 because molfile indexing starts from 1
1753
+ let furthestAtomIdx = atoms.x.reduce((furthestIdx, x, idx) => {
1746
1754
  if (idx === existingRgroupIdx)
1747
1755
  return furthestIdx; // skip existing r-group
1756
+ // also skip the atom bonded to the existing r-group
1757
+ if (idx === atomBondedToExistingRgroupIdx)
1758
+ return furthestIdx;
1748
1759
  const y = atoms.y[idx];
1749
1760
  const dist = Math.sqrt((x - existingRgroupX) ** 2 + (y - existingRgroupY) ** 2);
1750
1761
  return dist > Math.sqrt((atoms.x[furthestIdx] - existingRgroupX) ** 2 +
1751
1762
  (atoms.y[furthestIdx] - existingRgroupY) ** 2) ? idx : furthestIdx;
1752
- }, 0);
1763
+ }, -1);
1764
+ if (furthestAtomIdx === -1) {
1765
+ furthestAtomIdx = atoms.x.length;
1766
+ // add pseudo-hydrogen atom, very relevant for stuff like NH2-R
1767
+ atoms.x = new Float32Array([...atoms.x, -existingRgroupX]);
1768
+ atoms.y = new Float32Array([...atoms.y, -existingRgroupY]);
1769
+ atoms.atomTypes = [...atoms.atomTypes, 'H'];
1770
+ atoms.kwargs = [...atoms.kwargs, ''];
1771
+ bonds.atomPairs.push([atomBondedToExistingRgroupIdx + 1, furthestAtomIdx + 1]); // +1 because molfile indexing starts from 1
1772
+ bonds.bondTypes = new Uint32Array([...bonds.bondTypes, 1]); // single bond
1773
+ bonds.kwargs.set(bonds.atomPairs.length - 1, ''); // empty kwargs for the new bond
1774
+ }
1753
1775
  capGroupIdxMap.set(furthestAtomIdx + 1, missingRGroup); // +1 because molfile indexing starts from 1
1754
1776
  // finaly splice the capGroups array in correct place
1755
1777
  if (missingRGroup === 1)
@@ -2096,7 +2118,9 @@ function removeRgroupKwargs(monomerGraph) {
2096
2118
  /** Remove node 'removedNode' and the associated bonds. Notice, numeration of
2097
2119
  * nodes in molfiles starts from 1, not 0
2098
2120
  * @param {MolGraph} monomerGraph - monomer graph
2099
- * @param {number} removedNode - node to be removed*/
2121
+ * @param {number} removedNode - node to be removed
2122
+ * @return {{removedAtom: string} | undefined} - removed atom type, if any
2123
+ * */
2100
2124
  function removeNodeAndBonds(monomerGraph, removedNode) {
2101
2125
  if (typeof removedNode !== 'undefined') {
2102
2126
  const removedNodeIdx = removedNode - 1;
@@ -2104,7 +2128,7 @@ function removeNodeAndBonds(monomerGraph, removedNode) {
2104
2128
  const bonds = monomerGraph.bonds;
2105
2129
  const meta = monomerGraph.meta;
2106
2130
  // remove the node from atoms
2107
- atoms.atomTypes.splice(removedNodeIdx, 1);
2131
+ const removedAtomType = atoms.atomTypes.splice(removedNodeIdx, 1)[0];
2108
2132
  atoms.x = spliceTypedArray(Float32Array, atoms.x, removedNodeIdx, 1);
2109
2133
  atoms.y = spliceTypedArray(Float32Array, atoms.y, removedNodeIdx, 1);
2110
2134
  atoms.kwargs.splice(removedNodeIdx, 1);
@@ -2158,6 +2182,7 @@ function removeNodeAndBonds(monomerGraph, removedNode) {
2158
2182
  bonds.kwargs.set(key - 1, value);
2159
2183
  }
2160
2184
  });
2185
+ return removedAtomType ? { removedAtom: removedAtomType } : undefined;
2161
2186
  }
2162
2187
  }
2163
2188
  // todo: rewrite the following two functions using templates,
@@ -3230,6 +3255,15 @@ class MonomerPlacer extends _cell_renderer_back_base__WEBPACK_IMPORTED_MODULE_5_
3230
3255
  return renderMultiline === 'true';
3231
3256
  }
3232
3257
  calculateMultiLineLayoutDynamic(g, w, h, subParts, positionShift, maxLengthOfMonomer) {
3258
+ if (this.dirty) {
3259
+ try {
3260
+ this.reset();
3261
+ }
3262
+ catch (err) {
3263
+ const [errMsg, errStack] = (0,_err_info__WEBPACK_IMPORTED_MODULE_7__.errInfo)(err);
3264
+ this.logger.error(errMsg, undefined, errStack);
3265
+ }
3266
+ }
3233
3267
  // --- 1. Setup ---
3234
3268
  const { lineHeight, monomerSpacing } = this.calculateFontBasedSpacing(g);
3235
3269
  const availableWidth = w - (this.padding * 2);
@@ -3507,6 +3541,7 @@ class MonomerPlacer extends _cell_renderer_back_base__WEBPACK_IMPORTED_MODULE_5_
3507
3541
  this.setMonomerLengthLimit(maxLengthOfMonomer);
3508
3542
  this.setSeparatorWidth(sh.isMsa() ? msaGapLength : gapLength);
3509
3543
  tableCol.temp[".mm.cellRenderer.settingsChanged" /* MmcrTemps.rendererSettingsChanged */] = _cell_renderer_consts__WEBPACK_IMPORTED_MODULE_9__.rendererSettingsChangedState.false;
3544
+ this.dirty = true;
3510
3545
  }
3511
3546
  const rowIdx = gridCell.cell.rowIndex;
3512
3547
  const value = gridCell.cell.value;
@@ -3533,7 +3568,7 @@ class MonomerPlacer extends _cell_renderer_back_base__WEBPACK_IMPORTED_MODULE_5_
3533
3568
  return wu__WEBPACK_IMPORTED_MODULE_2___default().count(0).take(seqSS.length).slice(positionShift).map((posIdx) => seqSS.getCanonical(posIdx)).toArray();
3534
3569
  })();
3535
3570
  const selectedPosition = Number.parseInt(tableCol.getTag(_macromolecule__WEBPACK_IMPORTED_MODULE_4__.TAGS.selectedPosition) ?? '-200');
3536
- const shouldUseMultiLine = this.shouldUseMultilineRendering(tableCol) && drawStyle !== _cell_renderer__WEBPACK_IMPORTED_MODULE_8__.DrawStyle.MSA;
3571
+ const shouldUseMultiLine = this.shouldUseMultilineRendering(tableCol);
3537
3572
  if (shouldUseMultiLine) {
3538
3573
  const currentCellBounds = [];
3539
3574
  const layout = this.calculateMultiLineLayoutDynamic(g, w, h, subParts, positionShift, maxLengthOfMonomer);
@@ -4028,6 +4063,7 @@ __webpack_require__.r(__webpack_exports__);
4028
4063
  /* harmony export */ BioTags: () => (/* binding */ TAGS),
4029
4064
  /* harmony export */ GAP_SYMBOL: () => (/* binding */ GAP_SYMBOL),
4030
4065
  /* harmony export */ GapOriginals: () => (/* binding */ GapOriginals),
4066
+ /* harmony export */ MONOMER_MOTIF_SPLITTER: () => (/* binding */ MONOMER_MOTIF_SPLITTER),
4031
4067
  /* harmony export */ NOTATION: () => (/* binding */ NOTATION),
4032
4068
  /* harmony export */ TAGS: () => (/* binding */ TAGS),
4033
4069
  /* harmony export */ candidateAlphabets: () => (/* binding */ candidateAlphabets),
@@ -4097,6 +4133,7 @@ const GapOriginals = {
4097
4133
  [NOTATION.SEPARATOR]: '',
4098
4134
  [NOTATION.HELM]: '*',
4099
4135
  };
4136
+ const MONOMER_MOTIF_SPLITTER = ' , ';
4100
4137
  //# sourceMappingURL=consts.js.map
4101
4138
 
4102
4139
  /***/ }),
@@ -4111,6 +4148,7 @@ const GapOriginals = {
4111
4148
  __webpack_require__.r(__webpack_exports__);
4112
4149
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
4113
4150
  /* harmony export */ ALPHABET: () => (/* reexport safe */ _consts__WEBPACK_IMPORTED_MODULE_0__.ALPHABET),
4151
+ /* harmony export */ MONOMER_MOTIF_SPLITTER: () => (/* reexport safe */ _consts__WEBPACK_IMPORTED_MODULE_0__.MONOMER_MOTIF_SPLITTER),
4114
4152
  /* harmony export */ NOTATION: () => (/* reexport safe */ _consts__WEBPACK_IMPORTED_MODULE_0__.NOTATION),
4115
4153
  /* harmony export */ TAGS: () => (/* reexport safe */ _consts__WEBPACK_IMPORTED_MODULE_0__.TAGS),
4116
4154
  /* harmony export */ candidateAlphabets: () => (/* reexport safe */ _consts__WEBPACK_IMPORTED_MODULE_0__.candidateAlphabets),
@@ -4129,6 +4167,7 @@ __webpack_require__.r(__webpack_exports__);
4129
4167
  /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ "./node_modules/@datagrok-libraries/bio/src/utils/macromolecule/utils.js");
4130
4168
 
4131
4169
 
4170
+
4132
4171
  //# sourceMappingURL=index.js.map
4133
4172
 
4134
4173
  /***/ }),