@teselagen/bio-parsers 0.4.18 → 0.4.19

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