@teselagen/bio-parsers 0.4.18 → 0.4.20

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 (6) hide show
  1. package/index.cjs +380 -116
  2. package/index.js +380 -116
  3. package/index.umd.cjs +380 -116
  4. package/package.json +3 -3
  5. package/index.mjs +0 -32872
  6. package/index.umd.js +0 -32876
package/index.js CHANGED
@@ -1396,14 +1396,14 @@ function baseIsSet(value) {
1396
1396
  __name(baseIsSet, "baseIsSet");
1397
1397
  var nodeIsSet = nodeUtil && nodeUtil.isSet;
1398
1398
  var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
1399
- var CLONE_DEEP_FLAG$2 = 1, CLONE_FLAT_FLAG$1 = 2, CLONE_SYMBOLS_FLAG$2 = 4;
1399
+ var CLONE_DEEP_FLAG$2 = 1, CLONE_FLAT_FLAG$1 = 2, CLONE_SYMBOLS_FLAG$3 = 4;
1400
1400
  var argsTag$1 = "[object Arguments]", arrayTag$1 = "[object Array]", boolTag$1 = "[object Boolean]", dateTag$1 = "[object Date]", errorTag$1 = "[object Error]", funcTag = "[object Function]", genTag = "[object GeneratorFunction]", mapTag$1 = "[object Map]", numberTag$1 = "[object Number]", objectTag$1 = "[object Object]", regexpTag$1 = "[object RegExp]", setTag$1 = "[object Set]", stringTag$1 = "[object String]", symbolTag$1 = "[object Symbol]", weakMapTag = "[object WeakMap]";
1401
1401
  var arrayBufferTag$1 = "[object ArrayBuffer]", dataViewTag$1 = "[object DataView]", float32Tag = "[object Float32Array]", float64Tag = "[object Float64Array]", int8Tag = "[object Int8Array]", int16Tag = "[object Int16Array]", int32Tag = "[object Int32Array]", uint8Tag = "[object Uint8Array]", uint8ClampedTag = "[object Uint8ClampedArray]", uint16Tag = "[object Uint16Array]", uint32Tag = "[object Uint32Array]";
1402
1402
  var cloneableTags = {};
1403
1403
  cloneableTags[argsTag$1] = cloneableTags[arrayTag$1] = cloneableTags[arrayBufferTag$1] = cloneableTags[dataViewTag$1] = cloneableTags[boolTag$1] = cloneableTags[dateTag$1] = cloneableTags[float32Tag] = cloneableTags[float64Tag] = cloneableTags[int8Tag] = cloneableTags[int16Tag] = cloneableTags[int32Tag] = cloneableTags[mapTag$1] = cloneableTags[numberTag$1] = cloneableTags[objectTag$1] = cloneableTags[regexpTag$1] = cloneableTags[setTag$1] = cloneableTags[stringTag$1] = cloneableTags[symbolTag$1] = cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
1404
1404
  cloneableTags[errorTag$1] = cloneableTags[funcTag] = cloneableTags[weakMapTag] = false;
1405
1405
  function baseClone(value, bitmask, customizer, key, object, stack) {
1406
- var result, isDeep = bitmask & CLONE_DEEP_FLAG$2, isFlat = bitmask & CLONE_FLAT_FLAG$1, isFull = bitmask & CLONE_SYMBOLS_FLAG$2;
1406
+ var result, isDeep = bitmask & CLONE_DEEP_FLAG$2, isFlat = bitmask & CLONE_FLAT_FLAG$1, isFull = bitmask & CLONE_SYMBOLS_FLAG$3;
1407
1407
  if (customizer) {
1408
1408
  result = object ? customizer(value, key, object, stack) : customizer(value);
1409
1409
  }
@@ -1463,6 +1463,11 @@ function baseClone(value, bitmask, customizer, key, object, stack) {
1463
1463
  return result;
1464
1464
  }
1465
1465
  __name(baseClone, "baseClone");
1466
+ var CLONE_SYMBOLS_FLAG$2 = 4;
1467
+ function clone(value) {
1468
+ return baseClone(value, CLONE_SYMBOLS_FLAG$2);
1469
+ }
1470
+ __name(clone, "clone");
1466
1471
  var CLONE_DEEP_FLAG$1 = 1, CLONE_SYMBOLS_FLAG$1 = 4;
1467
1472
  function cloneDeep(value) {
1468
1473
  return baseClone(value, CLONE_DEEP_FLAG$1 | CLONE_SYMBOLS_FLAG$1);
@@ -2405,6 +2410,45 @@ function trimRangeByAnotherRange(rangeToBeTrimmed, trimmingRange, sequenceLength
2405
2410
  }
2406
2411
  }
2407
2412
  __name(trimRangeByAnotherRange, "trimRangeByAnotherRange");
2413
+ function provideInclusiveOptions(funToWrap) {
2414
+ return function() {
2415
+ const args = Array.prototype.slice.call(arguments);
2416
+ const options = args[args.length - 1];
2417
+ if (options && (options.inclusive1BasedEnd || options.inclusive1BasedStart)) {
2418
+ args.forEach(function(arg, index) {
2419
+ if (arg && arg.start > -1 && options.inclusive1BasedStart) {
2420
+ args[index] = assign(arg, { start: arg.start - 1 });
2421
+ }
2422
+ if (arg && arg.end > -1 && options.inclusive1BasedEnd) {
2423
+ args[index] = assign(arg, { end: arg.end - 1 });
2424
+ }
2425
+ });
2426
+ }
2427
+ let returnVal = funToWrap.apply(this, args);
2428
+ if (returnVal && returnVal.start > -1 && options && options.inclusive1BasedStart) {
2429
+ returnVal = assign(returnVal, { start: returnVal.start + 1 });
2430
+ }
2431
+ if (returnVal && returnVal.end > -1 && options && options.inclusive1BasedEnd) {
2432
+ returnVal = assign(returnVal, { end: returnVal.end + 1 });
2433
+ }
2434
+ return returnVal;
2435
+ };
2436
+ }
2437
+ __name(provideInclusiveOptions, "provideInclusiveOptions");
2438
+ const getRangeLength = provideInclusiveOptions(getRangeLength$1);
2439
+ function getRangeLength$1(range, rangeMax) {
2440
+ let toRet;
2441
+ if (range.end < range.start) {
2442
+ toRet = rangeMax - range.start + range.end + 1;
2443
+ } else {
2444
+ toRet = range.end - range.start + 1;
2445
+ }
2446
+ if (range.overlapsSelf && rangeMax) {
2447
+ toRet += rangeMax;
2448
+ }
2449
+ return toRet;
2450
+ }
2451
+ __name(getRangeLength$1, "getRangeLength$1");
2408
2452
  function isRangeWithinRange(rangeToCheck, containingRange, maxLength) {
2409
2453
  const ranges = trimRangeByAnotherRange(
2410
2454
  rangeToCheck,
@@ -2416,6 +2460,22 @@ function isRangeWithinRange(rangeToCheck, containingRange, maxLength) {
2416
2460
  return !ranges;
2417
2461
  }
2418
2462
  __name(isRangeWithinRange, "isRangeWithinRange");
2463
+ function isPositionWithinRange(position, range, sequenceLength, includeStartEdge, includeEndEdge) {
2464
+ const ranges = splitRangeIntoTwoPartsIfItIsCircular(range, sequenceLength);
2465
+ const positionFits = ranges.some(function(range2) {
2466
+ if (position < range2.start) {
2467
+ return false;
2468
+ } else {
2469
+ if (position <= range2.end) {
2470
+ return true;
2471
+ } else {
2472
+ return false;
2473
+ }
2474
+ }
2475
+ });
2476
+ return positionFits;
2477
+ }
2478
+ __name(isPositionWithinRange, "isPositionWithinRange");
2419
2479
  function normalizePositionByRangeLength(pPosition, sequenceLength, isInBetweenPositions) {
2420
2480
  let position = pPosition;
2421
2481
  if (position < 0) {
@@ -2426,6 +2486,23 @@ function normalizePositionByRangeLength(pPosition, sequenceLength, isInBetweenPo
2426
2486
  return position < 0 ? 0 : position > sequenceLength - 1 ? sequenceLength - 1 : position;
2427
2487
  }
2428
2488
  __name(normalizePositionByRangeLength, "normalizePositionByRangeLength");
2489
+ function normalizeRange(range, sequenceLength) {
2490
+ return assign({}, range, {
2491
+ start: normalizePositionByRangeLength(range.start, sequenceLength),
2492
+ end: normalizePositionByRangeLength(range.end, sequenceLength)
2493
+ });
2494
+ }
2495
+ __name(normalizeRange, "normalizeRange");
2496
+ function expandOrContractRangeByLength(range, shiftBy, shiftStart, sequenceLength) {
2497
+ const rangeToReturn = clone(range);
2498
+ if (shiftStart) {
2499
+ rangeToReturn.start -= shiftBy;
2500
+ } else {
2501
+ rangeToReturn.end += shiftBy;
2502
+ }
2503
+ return normalizeRange(rangeToReturn, sequenceLength);
2504
+ }
2505
+ __name(expandOrContractRangeByLength, "expandOrContractRangeByLength");
2429
2506
  function translateRange(rangeToBeAdjusted, translateBy, rangeLength) {
2430
2507
  return assign({}, rangeToBeAdjusted, {
2431
2508
  start: normalizePositionByRangeLength(
@@ -2439,6 +2516,118 @@ function translateRange(rangeToBeAdjusted, translateBy, rangeLength) {
2439
2516
  });
2440
2517
  }
2441
2518
  __name(translateRange, "translateRange");
2519
+ function flipRelativeRange(innerRange, outerRange, sequenceLength) {
2520
+ const isFullyContained = isRangeWithinRange(
2521
+ innerRange,
2522
+ outerRange,
2523
+ sequenceLength
2524
+ );
2525
+ if (isFullyContained) {
2526
+ return flipFullyContainedRange(innerRange, outerRange, sequenceLength);
2527
+ } else {
2528
+ return flipNonFullyContainedRange(innerRange, outerRange, sequenceLength);
2529
+ }
2530
+ }
2531
+ __name(flipRelativeRange, "flipRelativeRange");
2532
+ function flipNonFullyContainedRange(innerRange, outerRange, sequenceLength) {
2533
+ const outerFullyContained = isRangeWithinRange(
2534
+ outerRange,
2535
+ innerRange,
2536
+ sequenceLength
2537
+ );
2538
+ let flippedInnerRange;
2539
+ if (outerFullyContained) {
2540
+ const expandBy1 = getRangeLength(
2541
+ {
2542
+ start: innerRange.start,
2543
+ end: outerRange.start
2544
+ },
2545
+ sequenceLength
2546
+ ) - 1;
2547
+ flippedInnerRange = expandOrContractRangeByLength(
2548
+ outerRange,
2549
+ expandBy1,
2550
+ false,
2551
+ sequenceLength
2552
+ );
2553
+ const expandBy2 = getRangeLength(
2554
+ {
2555
+ end: innerRange.end,
2556
+ start: outerRange.end
2557
+ },
2558
+ sequenceLength
2559
+ ) - 1;
2560
+ flippedInnerRange = expandOrContractRangeByLength(
2561
+ flippedInnerRange,
2562
+ expandBy2,
2563
+ true,
2564
+ sequenceLength
2565
+ );
2566
+ } else {
2567
+ const overlaps = getOverlapsOfPotentiallyCircularRanges(
2568
+ innerRange,
2569
+ outerRange,
2570
+ sequenceLength
2571
+ );
2572
+ if (overlaps.length >= 1) {
2573
+ const firstOverlap = overlaps[0];
2574
+ const overlapExtendsForward = firstOverlap.start !== outerRange.start;
2575
+ const flippedTruncatedInner = flipFullyContainedRange(
2576
+ firstOverlap,
2577
+ outerRange,
2578
+ sequenceLength
2579
+ );
2580
+ const lengthToExtend = getRangeLength(innerRange, sequenceLength) - getRangeLength(flippedTruncatedInner, sequenceLength);
2581
+ flippedInnerRange = expandOrContractRangeByLength(
2582
+ flippedTruncatedInner,
2583
+ lengthToExtend,
2584
+ overlapExtendsForward,
2585
+ sequenceLength
2586
+ );
2587
+ } else {
2588
+ throw new Error(
2589
+ "This case (relative ranges that do not overlap) is unsupported! "
2590
+ );
2591
+ }
2592
+ }
2593
+ return flippedInnerRange;
2594
+ }
2595
+ __name(flipNonFullyContainedRange, "flipNonFullyContainedRange");
2596
+ function flipFullyContainedRange(innerRange, outerRange, sequenceLength) {
2597
+ const translateBy = -outerRange.start;
2598
+ const translatedOuterRange = translateRange(
2599
+ outerRange,
2600
+ translateBy,
2601
+ sequenceLength
2602
+ );
2603
+ const translatedInnerRange = translateRange(
2604
+ innerRange,
2605
+ translateBy,
2606
+ sequenceLength
2607
+ );
2608
+ const translatedFlippedInnerRange = flipNonOriginSpanningContainedRange(
2609
+ translatedInnerRange,
2610
+ translatedOuterRange,
2611
+ sequenceLength
2612
+ );
2613
+ const flippedInnerRange = translateRange(
2614
+ translatedFlippedInnerRange,
2615
+ -translateBy,
2616
+ sequenceLength
2617
+ );
2618
+ return flippedInnerRange;
2619
+ }
2620
+ __name(flipFullyContainedRange, "flipFullyContainedRange");
2621
+ function flipNonOriginSpanningContainedRange(innerRange, outerRange, sequenceLength) {
2622
+ const offsetFromStart = innerRange.start - outerRange.start;
2623
+ const newInnerEnd = outerRange.end - offsetFromStart;
2624
+ const innerRangeLength = getRangeLength(innerRange, sequenceLength);
2625
+ return {
2626
+ end: newInnerEnd,
2627
+ start: newInnerEnd - (innerRangeLength - 1)
2628
+ };
2629
+ }
2630
+ __name(flipNonOriginSpanningContainedRange, "flipNonOriginSpanningContainedRange");
2442
2631
  function getSequenceWithinRange(range, sequence) {
2443
2632
  if (range.start < 0 || range.end < 0)
2444
2633
  return "";
@@ -3242,7 +3431,7 @@ __name(requireEmpty, "requireEmpty");
3242
3431
  return new RegExp(regexMatch[1], regexMatch[2]);
3243
3432
  }
3244
3433
  __name(cloneRegExp2, "cloneRegExp");
3245
- function clone(arg) {
3434
+ function clone2(arg) {
3246
3435
  if ((typeof arg === "undefined" ? "undefined" : _typeof(arg)) !== "object") {
3247
3436
  return arg;
3248
3437
  }
@@ -3250,7 +3439,7 @@ __name(requireEmpty, "requireEmpty");
3250
3439
  return null;
3251
3440
  }
3252
3441
  if (isArray2(arg)) {
3253
- return arg.map(clone);
3442
+ return arg.map(clone2);
3254
3443
  }
3255
3444
  if (arg instanceof Date) {
3256
3445
  return new Date(arg.getTime());
@@ -3261,12 +3450,12 @@ __name(requireEmpty, "requireEmpty");
3261
3450
  var cloned = {};
3262
3451
  for (var name in arg) {
3263
3452
  if (Object.prototype.hasOwnProperty.call(arg, name)) {
3264
- cloned[name] = clone(arg[name]);
3453
+ cloned[name] = clone2(arg[name]);
3265
3454
  }
3266
3455
  }
3267
3456
  return cloned;
3268
3457
  }
3269
- __name(clone, "clone");
3458
+ __name(clone2, "clone");
3270
3459
  var DiffContext = function(_Context) {
3271
3460
  inherits2(DiffContext2, _Context);
3272
3461
  function DiffContext2(left, right) {
@@ -3282,7 +3471,7 @@ __name(requireEmpty, "requireEmpty");
3282
3471
  key: "setResult",
3283
3472
  value: /* @__PURE__ */ __name(function setResult(result) {
3284
3473
  if (this.options.cloneDiffValues && (typeof result === "undefined" ? "undefined" : _typeof(result)) === "object") {
3285
- var clone$$1 = typeof this.options.cloneDiffValues === "function" ? this.options.cloneDiffValues : clone;
3474
+ var clone$$1 = typeof this.options.cloneDiffValues === "function" ? this.options.cloneDiffValues : clone2;
3286
3475
  if (_typeof(result[0]) === "object") {
3287
3476
  result[0] = clone$$1(result[0]);
3288
3477
  }
@@ -5594,7 +5783,7 @@ __name(requireEmpty, "requireEmpty");
5594
5783
  }, {
5595
5784
  key: "clone",
5596
5785
  value: /* @__PURE__ */ __name(function clone$$1(value) {
5597
- return clone(value);
5786
+ return clone2(value);
5598
5787
  }, "clone$$1")
5599
5788
  }]);
5600
5789
  return DiffPatcher2;
@@ -7118,123 +7307,167 @@ function getAminoAcidFromSequenceTriplet(sequenceString) {
7118
7307
  return proteinAlphabet[letter.toUpperCase()];
7119
7308
  }
7120
7309
  __name(getAminoAcidFromSequenceTriplet, "getAminoAcidFromSequenceTriplet");
7121
- function getAminoAcidDataForEachBaseOfDna(originalSequenceString, forward, optionalSubrangeRange, isProteinSequence) {
7310
+ function getNextTriplet(index, sequenceString, exonRange) {
7311
+ let triplet = "";
7312
+ let internalIndex;
7313
+ const codonPositions = [];
7314
+ const isBaseInExon = /* @__PURE__ */ __name((baseIndex) => exonRange.some(
7315
+ (r) => isPositionWithinRange(baseIndex, r, sequenceString.length)
7316
+ ), "isBaseInExon");
7317
+ for (internalIndex = index; internalIndex < sequenceString.length; internalIndex++) {
7318
+ if (triplet.length === 3) {
7319
+ break;
7320
+ }
7321
+ if (isBaseInExon(internalIndex)) {
7322
+ triplet += sequenceString[internalIndex];
7323
+ codonPositions.push(internalIndex);
7324
+ }
7325
+ }
7326
+ return { triplet, basesRead: internalIndex - index, codonPositions };
7327
+ }
7328
+ __name(getNextTriplet, "getNextTriplet");
7329
+ function getTranslatedSequenceProperties(originalSequenceString, forward, optionalSubrangeRange, isProteinSequence) {
7122
7330
  const originalSequenceStringLength = isProteinSequence ? originalSequenceString.length * 3 : originalSequenceString.length;
7123
7331
  let sequenceString = originalSequenceString;
7124
- let startOffset = 0;
7332
+ const translationRange = { start: 0, end: originalSequenceStringLength - 1 };
7125
7333
  if (optionalSubrangeRange) {
7126
7334
  sequenceString = getSequenceWithinRange(
7127
7335
  optionalSubrangeRange,
7128
7336
  originalSequenceString
7129
7337
  );
7130
- startOffset = optionalSubrangeRange.start;
7338
+ translationRange.start = optionalSubrangeRange.start;
7339
+ translationRange.end = optionalSubrangeRange.end;
7131
7340
  }
7132
7341
  const sequenceStringLength = isProteinSequence ? sequenceString.length * 3 : sequenceString.length;
7133
- const aminoAcidDataForEachBaseOfDNA = [];
7134
- let codonRange;
7135
- let revCompGapLength = 0;
7136
- let aminoAcidIndex = 0;
7137
- if (!forward) {
7138
- aminoAcidIndex = Math.floor((sequenceStringLength - 1) / 3);
7139
- revCompGapLength = sequenceStringLength % 3;
7140
- codonRange = translateRange(
7141
- {
7142
- start: 0,
7143
- end: revCompGapLength - 1
7144
- },
7145
- startOffset,
7342
+ if (!isProteinSequence && !forward) {
7343
+ sequenceString = getReverseComplementSequenceString(sequenceString);
7344
+ }
7345
+ const absoluteExonRange = !isProteinSequence && optionalSubrangeRange && optionalSubrangeRange.locations ? optionalSubrangeRange.locations : [translationRange];
7346
+ const exonRange = absoluteExonRange.map((range) => {
7347
+ let outputRange = translateRange(
7348
+ range,
7349
+ -translationRange.start,
7146
7350
  originalSequenceStringLength
7147
7351
  );
7148
- if (revCompGapLength > 0) {
7149
- for (let i = 0; i < revCompGapLength; i++) {
7150
- aminoAcidDataForEachBaseOfDNA.push({
7151
- aminoAcid: getAminoAcidFromSequenceTriplet("xxx"),
7152
- //fake xxx triplet returns the ambiguous X amino acid
7153
- positionInCodon: revCompGapLength - i - 1,
7154
- aminoAcidIndex,
7155
- sequenceIndex: codonRange.start + i,
7156
- codonRange,
7157
- fullCodon: false
7158
- });
7159
- }
7160
- aminoAcidIndex--;
7352
+ if (!forward) {
7353
+ outputRange = flipRelativeRange(
7354
+ outputRange,
7355
+ { start: 0, end: sequenceStringLength - 1 },
7356
+ sequenceStringLength
7357
+ );
7161
7358
  }
7359
+ return outputRange;
7360
+ });
7361
+ return {
7362
+ sequenceString,
7363
+ translationRange,
7364
+ sequenceStringLength,
7365
+ originalSequenceStringLength,
7366
+ exonRange
7367
+ };
7368
+ }
7369
+ __name(getTranslatedSequenceProperties, "getTranslatedSequenceProperties");
7370
+ function positionInCdsToPositionInMainSequence(index, forward, translationRange, mainSequenceLength) {
7371
+ let outputRange = translateRange(
7372
+ { start: index, end: index },
7373
+ translationRange.start,
7374
+ mainSequenceLength
7375
+ );
7376
+ if (!forward) {
7377
+ outputRange = flipRelativeRange(
7378
+ outputRange,
7379
+ translationRange,
7380
+ mainSequenceLength
7381
+ );
7162
7382
  }
7163
- for (let index = 2 + revCompGapLength; index < sequenceStringLength; index += 3) {
7383
+ return outputRange.start;
7384
+ }
7385
+ __name(positionInCdsToPositionInMainSequence, "positionInCdsToPositionInMainSequence");
7386
+ function getAminoAcidDataForEachBaseOfDna(originalSequenceString, forward, optionalSubrangeRange, isProteinSequence) {
7387
+ const {
7388
+ sequenceString,
7389
+ translationRange,
7390
+ sequenceStringLength,
7391
+ originalSequenceStringLength,
7392
+ exonRange
7393
+ } = getTranslatedSequenceProperties(
7394
+ originalSequenceString,
7395
+ forward,
7396
+ optionalSubrangeRange,
7397
+ isProteinSequence
7398
+ );
7399
+ const aminoAcidDataForEachBaseOfDNA = [];
7400
+ for (let index = 0; index < sequenceStringLength; index += 3) {
7164
7401
  let aminoAcid;
7402
+ const aminoAcidIndex = index / 3;
7403
+ let codonPositionsInCDS;
7404
+ let basesRead;
7165
7405
  if (isProteinSequence) {
7166
- aminoAcid = proteinAlphabet[sequenceString[(index - 2) / 3].toUpperCase()];
7406
+ codonPositionsInCDS = [0, 1, 2].map((i) => index + i);
7407
+ basesRead = 3;
7408
+ aminoAcid = proteinAlphabet[sequenceString[index / 3].toUpperCase()];
7167
7409
  } else {
7168
- let triplet = sequenceString.slice(index - 2, index + 1);
7169
- if (!forward) {
7170
- triplet = getReverseComplementSequenceString(triplet);
7171
- }
7172
- aminoAcid = getAminoAcidFromSequenceTriplet(triplet);
7173
- }
7174
- codonRange = translateRange(
7175
- {
7176
- start: index - 2,
7177
- end: index
7178
- },
7179
- startOffset,
7180
- originalSequenceStringLength
7410
+ const {
7411
+ triplet,
7412
+ basesRead: _basesRead,
7413
+ codonPositions
7414
+ } = getNextTriplet(index, sequenceString, exonRange);
7415
+ basesRead = _basesRead;
7416
+ codonPositionsInCDS = codonPositions;
7417
+ aminoAcid = triplet.length === 3 ? getAminoAcidFromSequenceTriplet(triplet) : getAminoAcidFromSequenceTriplet("xxx");
7418
+ }
7419
+ const absoluteCodonPositions = codonPositionsInCDS.map(
7420
+ (i) => positionInCdsToPositionInMainSequence(
7421
+ i,
7422
+ forward,
7423
+ translationRange,
7424
+ originalSequenceStringLength
7425
+ )
7181
7426
  );
7182
- aminoAcidDataForEachBaseOfDNA.push({
7183
- aminoAcid,
7184
- //gap amino acid
7185
- positionInCodon: forward ? 0 : 2,
7186
- aminoAcidIndex,
7187
- sequenceIndex: codonRange.start,
7188
- codonRange,
7189
- fullCodon: true
7190
- });
7191
- aminoAcidDataForEachBaseOfDNA.push({
7192
- aminoAcid,
7193
- //gap amino acid
7194
- positionInCodon: 1,
7195
- aminoAcidIndex,
7196
- sequenceIndex: codonRange.start + 1,
7197
- codonRange,
7198
- fullCodon: true
7199
- });
7200
- aminoAcidDataForEachBaseOfDNA.push({
7201
- aminoAcid,
7202
- //gap amino acid
7203
- positionInCodon: forward ? 2 : 0,
7204
- aminoAcidIndex,
7205
- sequenceIndex: codonRange.start + 2,
7206
- codonRange,
7207
- fullCodon: true
7208
- });
7209
- if (forward) {
7210
- aminoAcidIndex++;
7211
- } else {
7212
- aminoAcidIndex--;
7427
+ const codonRange = forward ? {
7428
+ start: absoluteCodonPositions[0],
7429
+ end: absoluteCodonPositions[codonPositionsInCDS.length - 1]
7430
+ } : {
7431
+ start: absoluteCodonPositions[codonPositionsInCDS.length - 1],
7432
+ end: absoluteCodonPositions[0]
7433
+ };
7434
+ let positionInCodon = 0;
7435
+ for (let i = 0; i < basesRead; i++) {
7436
+ const posInCds = i + index;
7437
+ if (codonPositionsInCDS.includes(posInCds)) {
7438
+ aminoAcidDataForEachBaseOfDNA.push({
7439
+ aminoAcid,
7440
+ positionInCodon,
7441
+ aminoAcidIndex,
7442
+ sequenceIndex: absoluteCodonPositions[i],
7443
+ codonRange,
7444
+ fullCodon: codonPositionsInCDS.length === 3
7445
+ });
7446
+ positionInCodon++;
7447
+ } else {
7448
+ aminoAcidDataForEachBaseOfDNA.push({
7449
+ aminoAcid: null,
7450
+ positionInCodon: null,
7451
+ aminoAcidIndex: null,
7452
+ sequenceIndex: positionInCdsToPositionInMainSequence(
7453
+ posInCds,
7454
+ forward,
7455
+ translationRange,
7456
+ originalSequenceStringLength
7457
+ ),
7458
+ codonRange: null,
7459
+ fullCodon: null
7460
+ });
7461
+ }
7213
7462
  }
7214
- }
7215
- const lengthOfEndBpsNotCoveredByAminoAcids = sequenceStringLength - aminoAcidDataForEachBaseOfDNA.length;
7216
- codonRange = translateRange(
7217
- {
7218
- start: sequenceStringLength - lengthOfEndBpsNotCoveredByAminoAcids,
7219
- end: sequenceStringLength - 1
7220
- },
7221
- startOffset,
7222
- originalSequenceStringLength
7223
- );
7224
- for (let j = 0; j < lengthOfEndBpsNotCoveredByAminoAcids; j++) {
7225
- aminoAcidDataForEachBaseOfDNA.push({
7226
- aminoAcid: getAminoAcidFromSequenceTriplet("xxx"),
7227
- //fake xxx triplet returns the gap amino acid
7228
- positionInCodon: j,
7229
- aminoAcidIndex,
7230
- sequenceIndex: codonRange.start + j,
7231
- fullCodon: false,
7232
- codonRange
7233
- });
7463
+ index += basesRead - codonPositionsInCDS.length;
7234
7464
  }
7235
7465
  if (sequenceStringLength !== aminoAcidDataForEachBaseOfDNA.length) {
7236
7466
  throw new Error("something went wrong!");
7237
7467
  }
7468
+ if (!forward) {
7469
+ aminoAcidDataForEachBaseOfDNA.reverse();
7470
+ }
7238
7471
  return aminoAcidDataForEachBaseOfDNA;
7239
7472
  }
7240
7473
  __name(getAminoAcidDataForEachBaseOfDna, "getAminoAcidDataForEachBaseOfDna");
@@ -7680,9 +7913,9 @@ const calcTmMethods = {
7680
7913
  // Helix initiation for deltaS
7681
7914
  R: 1.987,
7682
7915
  // Gas constant (cal/(K*mol)).
7683
- C: 5e-7,
7916
+ primerConc: 5e-7,
7684
7917
  // Oligo concentration. 0.5uM is typical for PCR.
7685
- Na: 0.05,
7918
+ monovalentCationConc: 0.05,
7686
7919
  // Monovalent salt concentration. 50mM is typical for PCR.
7687
7920
  /**
7688
7921
  * Calculates temperature for DNA sequence using a given algorithm.
@@ -7690,10 +7923,11 @@ const calcTmMethods = {
7690
7923
  * type - Either Teselagen.bio.tools.TemperatureCalculator.TABLE_BRESLAUER, TABLE_SUGIMOTO, or TABLE_UNIFIED
7691
7924
  * A - Helix initation for deltaS. Defaults to -10.8.
7692
7925
  * R - The gas constant, in cal/(K*mol). Defaults to 0.5e-6M.
7693
- * Na - THe monovalent salt concentration. Defaults to 50e-3M.
7926
+ * monovalentCationConc - THe monovalent salt concentration. Defaults to 50e-3M.
7694
7927
  * return - Temperature for the given sequence, in Celsius.
7695
7928
  */
7696
- calculateTemperature: function(sequence, type, A, R, C, Na) {
7929
+ calculateTemperature: function(_sequence, { type, A, R, primerConc, monovalentCationConc } = {}) {
7930
+ const sequence = _sequence.toLowerCase();
7697
7931
  if (typeof type === "undefined") {
7698
7932
  type = this.TABLE_BRESLAUER;
7699
7933
  } else if (type != this.TABLE_BRESLAUER && type != this.TABLE_UNIFIED && type != this.TABLE_SUGIMOTO) {
@@ -7705,11 +7939,11 @@ const calcTmMethods = {
7705
7939
  if (!R) {
7706
7940
  R = this.R;
7707
7941
  }
7708
- if (!C) {
7709
- C = this.C;
7942
+ if (!primerConc) {
7943
+ primerConc = this.primerConc;
7710
7944
  }
7711
- if (!Na) {
7712
- Na = this.Na;
7945
+ if (!monovalentCationConc) {
7946
+ monovalentCationConc = this.monovalentCationConc;
7713
7947
  }
7714
7948
  const sequenceLength = sequence.length;
7715
7949
  if (sequenceLength == 0) {
@@ -7740,11 +7974,8 @@ const calcTmMethods = {
7740
7974
  sumDeltaH = sumDeltaH + neighbors[i] * deltaHTable[i];
7741
7975
  sumDeltaS = sumDeltaS + neighbors[i] * deltaSTable[i];
7742
7976
  }
7743
- const temperature = -1e3 * sumDeltaH / (A + -sumDeltaS + R * Math.log(C / 4)) - 273.15 + 16.6 * Math.LOG10E * Math.log(Na);
7744
- if (temperature < 0) {
7745
- return 0;
7746
- }
7747
- return temperature.toFixed(2);
7977
+ const temperature = -1e3 * sumDeltaH / (A + -sumDeltaS + R * Math.log(primerConc / 4)) - 273.15 + 16.6 * Math.LOG10E * Math.log(monovalentCationConc);
7978
+ return temperature;
7748
7979
  },
7749
7980
  /**
7750
7981
  * @private
@@ -7814,6 +8045,39 @@ const calcTmMethods = {
7814
8045
  return null;
7815
8046
  }
7816
8047
  },
8048
+ // "AA/TT": -7.9, 7.9
8049
+ // "AT/TA": -7.2, 7.2
8050
+ // "AC/TG": -8.4, 8.4
8051
+ // "AG/TC": -7.8, 7.8
8052
+ // "TT/AA": -7.9, 7.9
8053
+ // "TA/AT": -7.2, 7.2
8054
+ // "TG/AC": -8.5, 8.2
8055
+ // "TC/AG": -8.2, 8.5
8056
+ // "CC/GG": -8.0, 8.0
8057
+ // "CA/GT": -8.5, 8.5
8058
+ // "CT/GA": -7.8, 7.8
8059
+ // "CG/GC": -10.6, 10.6
8060
+ // "GG/CC": -8.0, 8.0
8061
+ // "GA/CT": -8.2, 8.2,
8062
+ // "GT/CA": -8.4, 8.4
8063
+ // "GC/CG": -9.8, 9.8
8064
+ // aa, at, ac, ag, tt, ta, tc, tg, cc, ca, ct, cg, gg, ga, gt, gc
8065
+ // "AA/TT": -22.2,22.2,
8066
+ // "AT/TA": -20.4,20.4,
8067
+ // "AC/TG": -22.4,22.4,
8068
+ // "AG/TC": -21.0,21.0,
8069
+ // "TT/AA": -22.2,22.2,
8070
+ // "TA/AT": -21.3,21.3,
8071
+ // "TC/AG": -22.2,22.2,
8072
+ // "TG/AC": -22.7,22.7,
8073
+ // "CC/GG": -19.9,19.9,
8074
+ // "CA/GT": -22.7,22.7,
8075
+ // "CT/GA": -21.0,21.0,
8076
+ // "CG/GC": -27.2,27.2,
8077
+ // "GG/CC": -19.9,19.9,
8078
+ // "GT/CA": -22.4,22.2,
8079
+ // "GA/CT": -22.2,22.4,
8080
+ // "GC/CG": -24.4,24.4
7817
8081
  /**
7818
8082
  * @private
7819
8083
  * Function to return deltaS table for given algorithm.