@teselagen/sequence-utils 0.3.41 → 0.3.42-beta.1
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/DNAComplementMap.d.ts +1 -1
- package/README.md +2 -8
- package/addGapsToSeqReads.d.ts +16 -3
- package/adjustAnnotationsToInsert.d.ts +2 -1
- package/adjustBpsToReplaceOrInsert.d.ts +2 -1
- package/aliasedEnzymesByName.d.ts +37 -1
- package/aminoAcidToDegenerateDnaMap.d.ts +1 -31
- package/aminoAcidToDegenerateRnaMap.d.ts +1 -1
- package/annotateSingleSeq.d.ts +5 -4
- package/annotationTypes.d.ts +2 -2
- package/autoAnnotate.d.ts +17 -8
- package/bioData.d.ts +10 -58
- package/calculateEndStability.d.ts +1 -1
- package/calculateNebTa.d.ts +6 -1
- package/calculateNebTm.d.ts +6 -4
- package/calculatePercentGC.d.ts +1 -1
- package/calculateSantaLuciaTm.d.ts +28 -114
- package/calculateTm.d.ts +13 -1
- package/computeDigestFragments.d.ts +30 -24
- package/condensePairwiseAlignmentDifferences.d.ts +1 -1
- package/convertAACaretPositionOrRangeToDna.d.ts +2 -1
- package/convertDnaCaretPositionOrRangeToAA.d.ts +2 -1
- package/cutSequenceByRestrictionEnzyme.d.ts +2 -1
- package/defaultEnzymesByName.d.ts +2 -1
- package/degenerateDnaToAminoAcidMap.d.ts +1 -1
- package/degenerateRnaToAminoAcidMap.d.ts +1 -1
- package/deleteSequenceDataAtRange.d.ts +2 -1
- package/diffUtils.d.ts +9 -7
- package/doesEnzymeChopOutsideOfRecognitionSite.d.ts +2 -1
- package/featureTypesAndColors.d.ts +19 -6
- package/filterSequenceString.d.ts +14 -10
- package/findApproxMatches.d.ts +7 -1
- package/findNearestRangeOfSequenceOverlapToPosition.d.ts +2 -1
- package/findOrfsInPlasmid.d.ts +2 -11
- package/findSequenceMatches.d.ts +11 -1
- package/generateAnnotations.d.ts +2 -1
- package/generateSequenceData.d.ts +8 -13
- package/getAllInsertionsInSeqReads.d.ts +11 -1
- package/getAminoAcidDataForEachBaseOfDna.d.ts +6 -5
- package/getAminoAcidFromSequenceTriplet.d.ts +1 -1
- package/getAminoAcidStringFromSequenceString.d.ts +3 -1
- package/getCodonRangeForAASliver.d.ts +3 -4
- package/getComplementAminoAcidStringFromSequenceString.d.ts +1 -1
- package/getComplementSequenceAndAnnotations.d.ts +5 -1
- package/getComplementSequenceString.d.ts +1 -1
- package/getCutsiteType.d.ts +2 -1
- package/getCutsitesFromSequence.d.ts +2 -1
- package/getDegenerateDnaStringFromAAString.d.ts +1 -1
- package/getDegenerateRnaStringFromAAString.d.ts +1 -1
- package/getDigestFragmentsForCutsites.d.ts +4 -1
- package/getDigestFragmentsForRestrictionEnzymes.d.ts +8 -1
- package/getInsertBetweenVals.d.ts +2 -1
- package/getLeftAndRightOfSequenceInRangeGivenPosition.d.ts +2 -1
- package/getOrfsFromSequence.d.ts +17 -11
- package/getOverlapBetweenTwoSequences.d.ts +2 -1
- package/getPossiblePartsFromSequenceAndEnzymes.d.ts +18 -1
- package/getReverseAminoAcidStringFromSequenceString.d.ts +1 -1
- package/getReverseComplementAminoAcidStringFromSequenceString.d.ts +1 -1
- package/getReverseComplementAnnotation.d.ts +11 -1
- package/getReverseComplementSequenceAndAnnotations.d.ts +5 -1
- package/getReverseComplementSequenceString.d.ts +1 -1
- package/getReverseSequenceString.d.ts +1 -1
- package/getSequenceDataBetweenRange.d.ts +9 -1
- package/getVirtualDigest.d.ts +11 -10
- package/guessIfSequenceIsDnaAndNotProtein.d.ts +5 -1
- package/index.cjs +762 -495
- package/index.d.ts +9 -5
- package/index.js +763 -496
- package/index.umd.cjs +762 -495
- package/insertGapsIntoRefSeq.d.ts +2 -1
- package/insertSequenceDataAtPositionOrRange.d.ts +10 -1
- package/isEnzymeType2S.d.ts +2 -1
- package/mapAnnotationsToRows.d.ts +9 -1
- package/package.json +9 -6
- package/prepareCircularViewData.d.ts +2 -1
- package/prepareRowData.d.ts +7 -3
- package/proteinAlphabet.d.ts +1 -1
- package/rotateBpsToPosition.d.ts +1 -1
- package/rotateSequenceDataToPosition.d.ts +3 -1
- package/shiftAnnotationsByLen.d.ts +4 -3
- package/src/{addGapsToSeqReads.js → addGapsToSeqReads.ts} +33 -14
- package/src/{adjustAnnotationsToInsert.js → adjustAnnotationsToInsert.ts} +6 -5
- package/src/{adjustBpsToReplaceOrInsert.js → adjustBpsToReplaceOrInsert.ts} +31 -8
- package/src/{aliasedEnzymesByName.js → aliasedEnzymesByName.ts} +4 -1
- package/src/{aminoAcidToDegenerateDnaMap.js → aminoAcidToDegenerateDnaMap.ts} +1 -1
- package/src/{annotateSingleSeq.js → annotateSingleSeq.ts} +11 -3
- package/src/autoAnnotate.test.js +0 -1
- package/src/{autoAnnotate.js → autoAnnotate.ts} +69 -24
- package/src/{bioData.js → bioData.ts} +2 -2
- package/src/{calculateEndStability.js → calculateEndStability.ts} +21 -16
- package/src/{calculateNebTa.js → calculateNebTa.ts} +20 -8
- package/src/{calculateNebTm.js → calculateNebTm.ts} +15 -9
- package/src/{calculatePercentGC.js → calculatePercentGC.ts} +1 -1
- package/src/{calculateSantaLuciaTm.js → calculateSantaLuciaTm.ts} +29 -22
- package/src/{calculateTm.js → calculateTm.ts} +50 -59
- package/src/{computeDigestFragments.js → computeDigestFragments.ts} +92 -36
- package/src/{condensePairwiseAlignmentDifferences.js → condensePairwiseAlignmentDifferences.ts} +4 -4
- package/src/{convertAACaretPositionOrRangeToDna.js → convertAACaretPositionOrRangeToDna.ts} +8 -4
- package/src/{convertDnaCaretPositionOrRangeToAA.js → convertDnaCaretPositionOrRangeToAA.ts} +8 -4
- package/src/cutSequenceByRestrictionEnzyme.ts +345 -0
- package/src/{defaultEnzymesByName.js → defaultEnzymesByName.ts} +2 -1
- package/src/deleteSequenceDataAtRange.ts +13 -0
- package/src/diffUtils.ts +80 -0
- package/src/doesEnzymeChopOutsideOfRecognitionSite.ts +16 -0
- package/src/{featureTypesAndColors.js → featureTypesAndColors.ts} +29 -14
- package/src/{filterSequenceString.js → filterSequenceString.ts} +51 -21
- package/src/{findApproxMatches.js → findApproxMatches.ts} +14 -6
- package/src/{findNearestRangeOfSequenceOverlapToPosition.js → findNearestRangeOfSequenceOverlapToPosition.ts} +13 -9
- package/src/{findOrfsInPlasmid.js → findOrfsInPlasmid.ts} +8 -7
- package/src/{findSequenceMatches.js → findSequenceMatches.ts} +31 -13
- package/src/{generateAnnotations.js → generateAnnotations.ts} +14 -9
- package/src/{generateSequenceData.js → generateSequenceData.ts} +19 -13
- package/src/{getAllInsertionsInSeqReads.js → getAllInsertionsInSeqReads.ts} +19 -2
- package/src/{getAminoAcidDataForEachBaseOfDna.js → getAminoAcidDataForEachBaseOfDna.ts} +36 -30
- package/src/{getAminoAcidFromSequenceTriplet.js → getAminoAcidFromSequenceTriplet.ts} +9 -4
- package/src/{getAminoAcidStringFromSequenceString.js → getAminoAcidStringFromSequenceString.ts} +14 -7
- package/src/{getCodonRangeForAASliver.js → getCodonRangeForAASliver.ts} +16 -6
- package/src/{getComplementAminoAcidStringFromSequenceString.js → getComplementAminoAcidStringFromSequenceString.ts} +5 -3
- package/src/{getComplementSequenceAndAnnotations.js → getComplementSequenceAndAnnotations.ts} +8 -6
- package/src/{getComplementSequenceString.js → getComplementSequenceString.ts} +5 -2
- package/src/getCutsiteType.ts +18 -0
- package/src/getCutsitesFromSequence.ts +22 -0
- package/src/getDegenerateDnaStringFromAAString.ts +15 -0
- package/src/getDegenerateRnaStringFromAAString.ts +15 -0
- package/src/{getDigestFragmentsForCutsites.js → getDigestFragmentsForCutsites.ts} +32 -14
- package/src/getDigestFragmentsForRestrictionEnzymes.ts +50 -0
- package/src/{getInsertBetweenVals.js → getInsertBetweenVals.ts} +8 -5
- package/src/{getLeftAndRightOfSequenceInRangeGivenPosition.js → getLeftAndRightOfSequenceInRangeGivenPosition.ts} +11 -10
- package/src/{getMassOfAaString.js → getMassOfAaString.ts} +4 -2
- package/src/{getOrfsFromSequence.js → getOrfsFromSequence.ts} +27 -7
- package/src/{getOverlapBetweenTwoSequences.js → getOverlapBetweenTwoSequences.ts} +4 -4
- package/src/{getPossiblePartsFromSequenceAndEnzymes.js → getPossiblePartsFromSequenceAndEnzymes.ts} +52 -25
- package/src/{getReverseAminoAcidStringFromSequenceString.js → getReverseAminoAcidStringFromSequenceString.ts} +4 -2
- package/src/{getReverseComplementAminoAcidStringFromSequenceString.js → getReverseComplementAminoAcidStringFromSequenceString.ts} +2 -2
- package/src/{getReverseComplementAnnotation.js → getReverseComplementAnnotation.ts} +4 -2
- package/src/getReverseComplementSequenceAndAnnotations.ts +45 -0
- package/src/{getReverseComplementSequenceString.js → getReverseComplementSequenceString.ts} +4 -4
- package/src/{getReverseSequenceString.js → getReverseSequenceString.ts} +1 -1
- package/src/getSequenceDataBetweenRange.test.js +6 -3
- package/src/{getSequenceDataBetweenRange.js → getSequenceDataBetweenRange.ts} +44 -29
- package/src/{getVirtualDigest.js → getVirtualDigest.ts} +20 -9
- package/src/{guessIfSequenceIsDnaAndNotProtein.js → guessIfSequenceIsDnaAndNotProtein.ts} +11 -5
- package/src/{index.test.js → index.test.ts} +9 -5
- package/src/{index.js → index.ts} +1 -0
- package/src/{insertGapsIntoRefSeq.js → insertGapsIntoRefSeq.ts} +7 -2
- package/src/{insertSequenceDataAtPositionOrRange.js → insertSequenceDataAtPositionOrRange.ts} +130 -56
- package/src/isEnzymeType2S.ts +5 -0
- package/src/mapAnnotationsToRows.ts +256 -0
- package/src/prepareCircularViewData.ts +24 -0
- package/src/{prepareRowData.js → prepareRowData.ts} +27 -8
- package/src/prepareRowData_output1.json +1 -0
- package/src/rotateBpsToPosition.ts +12 -0
- package/src/{rotateSequenceDataToPosition.js → rotateSequenceDataToPosition.ts} +11 -8
- package/src/{shiftAnnotationsByLen.js → shiftAnnotationsByLen.ts} +12 -5
- package/src/{threeLetterSequenceStringToAminoAcidMap.js → threeLetterSequenceStringToAminoAcidMap.ts} +29 -9
- package/src/{tidyUpAnnotation.js → tidyUpAnnotation.ts} +40 -18
- package/src/{tidyUpSequenceData.js → tidyUpSequenceData.ts} +83 -39
- package/src/types.ts +98 -0
- package/threeLetterSequenceStringToAminoAcidMap.d.ts +11 -921
- package/tidyUpAnnotation.d.ts +13 -11
- package/tidyUpSequenceData.d.ts +18 -1
- package/types.d.ts +96 -0
- package/addGapsToSeqReads.test.d.ts +0 -1
- package/adjustBpsToReplaceOrInsert.test.d.ts +0 -1
- package/aminoAcidToDnaRna.test.d.ts +0 -1
- package/annotateSingleSeq.test.d.ts +0 -1
- package/autoAnnotate.test.d.ts +0 -1
- package/calculateEndStability.test.d.ts +0 -1
- package/calculateNebTa.test.d.ts +0 -1
- package/calculateNebTm.test.d.ts +0 -1
- package/calculatePercentGC.test.d.ts +0 -1
- package/calculateSantaLuciaTm.test.d.ts +0 -1
- package/calculateTm.test.d.ts +0 -1
- package/computeDigestFragments.test.d.ts +0 -1
- package/condensePairwiseAlignmentDifferences.test.d.ts +0 -1
- package/convertAACaretPositionOrRangeToDna.test.d.ts +0 -1
- package/convertDnaCaretPositionOrRangeToAA.test.d.ts +0 -1
- package/cutSequenceByRestrictionEnzyme.test.d.ts +0 -1
- package/deleteSequenceDataAtRange.test.d.ts +0 -1
- package/diffUtils.test.d.ts +0 -1
- package/doesEnzymeChopOutsideOfRecognitionSite.test.d.ts +0 -1
- package/featureTypesAndColors.test.d.ts +0 -1
- package/filterSequenceString.test.d.ts +0 -1
- package/findApproxMatches.test.d.ts +0 -1
- package/findNearestRangeOfSequenceOverlapToPosition.test.d.ts +0 -1
- package/findSequenceMatches.test.d.ts +0 -1
- package/generateSequenceData.test.d.ts +0 -1
- package/getAllInsertionsInSeqReads.test.d.ts +0 -1
- package/getAminoAcidDataForEachBaseOfDna.test.d.ts +0 -1
- package/getAminoAcidStringFromSequenceString.test.d.ts +0 -1
- package/getComplementSequenceString.test.d.ts +0 -1
- package/getDigestFragmentsForRestrictionEnzymes.test.d.ts +0 -1
- package/getInsertBetweenVals.test.d.ts +0 -1
- package/getLeftAndRightOfSequenceInRangeGivenPosition.test.d.ts +0 -1
- package/getMassofAaString.test.d.ts +0 -1
- package/getOrfsFromSequence.test.d.ts +0 -1
- package/getOverlapBetweenTwoSequences.test.d.ts +0 -1
- package/getPossiblePartsFromSequenceAndEnzymes.test.d.ts +0 -1
- package/getReverseAminoAcidStringFromSequenceString.test.d.ts +0 -1
- package/getReverseComplementAnnotation.test.d.ts +0 -1
- package/getReverseComplementSequenceAndAnnotations.test.d.ts +0 -1
- package/getReverseComplementSequenceString.test.d.ts +0 -1
- package/getReverseSequenceString.test.d.ts +0 -1
- package/getSequenceDataBetweenRange.test.d.ts +0 -1
- package/getVirtualDigest.test.d.ts +0 -1
- package/guessIfSequenceIsDnaAndNotProtein.test.d.ts +0 -1
- package/index.test.d.ts +0 -1
- package/insertGapsIntoRefSeq.test.d.ts +0 -1
- package/insertSequenceDataAtPosition.test.d.ts +0 -1
- package/insertSequenceDataAtPositionOrRange.test.d.ts +0 -1
- package/mapAnnotationsToRows.test.d.ts +0 -1
- package/prepareCircularViewData.test.d.ts +0 -1
- package/prepareRowData.test.d.ts +0 -1
- package/rotateBpsToPosition.test.d.ts +0 -1
- package/rotateSequenceDataToPosition.test.d.ts +0 -1
- package/src/cutSequenceByRestrictionEnzyme.js +0 -301
- package/src/deleteSequenceDataAtRange.js +0 -5
- package/src/diffUtils.js +0 -63
- package/src/doesEnzymeChopOutsideOfRecognitionSite.js +0 -10
- package/src/getCutsiteType.js +0 -10
- package/src/getCutsitesFromSequence.js +0 -17
- package/src/getDegenerateDnaStringFromAAString.js +0 -8
- package/src/getDegenerateRnaStringFromAAString.js +0 -8
- package/src/getDigestFragmentsForRestrictionEnzymes.js +0 -27
- package/src/getReverseComplementSequenceAndAnnotations.js +0 -40
- package/src/isEnzymeType2S.js +0 -3
- package/src/mapAnnotationsToRows.js +0 -174
- package/src/prepareCircularViewData.js +0 -17
- package/src/rotateBpsToPosition.js +0 -9
- package/tidyUpSequenceData.test.d.ts +0 -1
- /package/src/{DNAComplementMap.js → DNAComplementMap.ts} +0 -0
- /package/src/{aminoAcidToDegenerateRnaMap.js → aminoAcidToDegenerateRnaMap.ts} +0 -0
- /package/src/{annotationTypes.js → annotationTypes.ts} +0 -0
- /package/src/{degenerateDnaToAminoAcidMap.js → degenerateDnaToAminoAcidMap.ts} +0 -0
- /package/src/{degenerateRnaToAminoAcidMap.js → degenerateRnaToAminoAcidMap.ts} +0 -0
- /package/src/{insertSequenceDataAtPosition.js → insertSequenceDataAtPosition.ts} +0 -0
- /package/src/{proteinAlphabet.js → proteinAlphabet.ts} +0 -0
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
import calculateTm from "./calculateNebTm";
|
|
2
2
|
|
|
3
|
+
interface NebTaOptions {
|
|
4
|
+
monovalentCationConc?: number;
|
|
5
|
+
polymerase?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
3
8
|
export default function calculateNebTa(
|
|
4
|
-
sequences,
|
|
5
|
-
primerConc,
|
|
6
|
-
{ monovalentCationConc, polymerase } = {}
|
|
7
|
-
) {
|
|
9
|
+
sequences: string[],
|
|
10
|
+
primerConc: number,
|
|
11
|
+
{ monovalentCationConc, polymerase }: NebTaOptions = {}
|
|
12
|
+
): number | string {
|
|
8
13
|
try {
|
|
9
14
|
if (sequences.length !== 2) {
|
|
10
15
|
throw new Error(
|
|
11
16
|
`${sequences.length} sequences received when 2 primers were expected`
|
|
12
17
|
);
|
|
13
18
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
// Type assertion or check return type of calculateTm if it can be number | string
|
|
20
|
+
// Assuming calculateTm returns number | string based on previous pattern
|
|
21
|
+
const meltingTemperatures = sequences.map(seq => {
|
|
22
|
+
const tm = calculateTm(seq, { monovalentCationConc, primerConc });
|
|
23
|
+
if (typeof tm !== "number") {
|
|
24
|
+
throw new Error(`Invalid Tm calculated for ${seq}: ${tm}`);
|
|
25
|
+
}
|
|
26
|
+
return tm;
|
|
27
|
+
});
|
|
28
|
+
|
|
17
29
|
meltingTemperatures.sort((a, b) => a - b);
|
|
18
30
|
const lowerMeltingTemp = meltingTemperatures[0];
|
|
19
|
-
let annealingTemp;
|
|
31
|
+
let annealingTemp: number;
|
|
20
32
|
if (polymerase === "Q5") {
|
|
21
33
|
// Ta = Tm_lower+1°C is standard for Q5
|
|
22
34
|
annealingTemp = lowerMeltingTemp + 1;
|
|
@@ -7,10 +7,16 @@ import calculatePercentGc from "./calculatePercentGC";
|
|
|
7
7
|
// - salt correction (for monovalent cations): Owczarzy (2004) Biochem 43:3537-54
|
|
8
8
|
|
|
9
9
|
// primer concentration & monovalent cation concentration in M
|
|
10
|
+
|
|
11
|
+
interface NebTmOptions {
|
|
12
|
+
monovalentCationConc?: number;
|
|
13
|
+
primerConc?: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
10
16
|
export default function calculateNebTm(
|
|
11
|
-
sequence,
|
|
12
|
-
{ monovalentCationConc = 0.05, primerConc = 0.0000005 } = {}
|
|
13
|
-
) {
|
|
17
|
+
sequence: string,
|
|
18
|
+
{ monovalentCationConc = 0.05, primerConc = 0.0000005 }: NebTmOptions = {}
|
|
19
|
+
): number | string {
|
|
14
20
|
try {
|
|
15
21
|
const checkForDegenerateBases = /[^atgc]/i.test(sequence);
|
|
16
22
|
if (checkForDegenerateBases) {
|
|
@@ -32,7 +38,7 @@ export default function calculateNebTm(
|
|
|
32
38
|
const celsiusToKelvin = 273.15;
|
|
33
39
|
// to convert the units of enthalpy from kilocal/mol to cal/mol
|
|
34
40
|
const kilocalToCal = 1000;
|
|
35
|
-
const sequenceToEnthalpyMap = {
|
|
41
|
+
const sequenceToEnthalpyMap: Record<string, number> = {
|
|
36
42
|
"AA/TT": -7.9,
|
|
37
43
|
"AT/TA": -7.2,
|
|
38
44
|
"TA/AT": -7.2,
|
|
@@ -52,7 +58,7 @@ export default function calculateNebTm(
|
|
|
52
58
|
initiationWithTerminalGC: 0.1,
|
|
53
59
|
initiationWithTerminalAT: 2.3
|
|
54
60
|
};
|
|
55
|
-
const sequenceToEntropyMap = {
|
|
61
|
+
const sequenceToEntropyMap: Record<string, number> = {
|
|
56
62
|
"AA/TT": -22.2,
|
|
57
63
|
"AT/TA": -20.4,
|
|
58
64
|
"TA/AT": -21.3,
|
|
@@ -76,11 +82,11 @@ export default function calculateNebTm(
|
|
|
76
82
|
if (i === 0 || i === seq.length - 1) {
|
|
77
83
|
// first or last nucleotide
|
|
78
84
|
if (seq[i] === "G" || seq[i] === "C") {
|
|
79
|
-
hi += sequenceToEnthalpyMap
|
|
80
|
-
si += sequenceToEntropyMap
|
|
85
|
+
hi += sequenceToEnthalpyMap["initiationWithTerminalGC"];
|
|
86
|
+
si += sequenceToEntropyMap["initiationWithTerminalGC"];
|
|
81
87
|
} else if (seq[i] === "A" || seq[i] === "T") {
|
|
82
|
-
hi += sequenceToEnthalpyMap
|
|
83
|
-
si += sequenceToEntropyMap
|
|
88
|
+
hi += sequenceToEnthalpyMap["initiationWithTerminalAT"];
|
|
89
|
+
si += sequenceToEntropyMap["initiationWithTerminalAT"];
|
|
84
90
|
}
|
|
85
91
|
}
|
|
86
92
|
if (i < seq.length - 1) {
|
|
@@ -19,6 +19,11 @@
|
|
|
19
19
|
* Proc Natl Acad Sci 95:1460-65
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
export interface SantaLuciaParams {
|
|
23
|
+
dH: number;
|
|
24
|
+
dS: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
22
27
|
// Primer3 custom parameters (fixed)
|
|
23
28
|
const PRIMER3_PARAMS = {
|
|
24
29
|
saltMonovalent: 50.0, // mM
|
|
@@ -30,7 +35,7 @@ const PRIMER3_PARAMS = {
|
|
|
30
35
|
|
|
31
36
|
// SantaLucia (1998) nearest-neighbor parameters
|
|
32
37
|
// dH in kcal/mol, dS in cal/K·mol
|
|
33
|
-
export const SANTA_LUCIA_NN = {
|
|
38
|
+
export const SANTA_LUCIA_NN: Record<string, SantaLuciaParams> = {
|
|
34
39
|
AA: { dH: -7.9, dS: -22.2 },
|
|
35
40
|
TT: { dH: -7.9, dS: -22.2 },
|
|
36
41
|
AT: { dH: -7.2, dS: -20.4 },
|
|
@@ -50,7 +55,7 @@ export const SANTA_LUCIA_NN = {
|
|
|
50
55
|
};
|
|
51
56
|
|
|
52
57
|
// Initiation parameters (SantaLucia 1998)
|
|
53
|
-
export const SANTA_LUCIA_INIT = {
|
|
58
|
+
export const SANTA_LUCIA_INIT: Record<string, SantaLuciaParams> = {
|
|
54
59
|
GC: { dH: 0.1, dS: -2.8 }, // initiation with terminal GC
|
|
55
60
|
AT: { dH: 2.3, dS: 4.1 } // initiation with terminal AT
|
|
56
61
|
};
|
|
@@ -62,7 +67,7 @@ export const SANTA_LUCIA_INIT = {
|
|
|
62
67
|
*
|
|
63
68
|
* @returns {number} - Effective monovalent concentration in mM
|
|
64
69
|
*/
|
|
65
|
-
function getEffectiveMonovalentConc() {
|
|
70
|
+
function getEffectiveMonovalentConc(): number {
|
|
66
71
|
let effectiveMono = PRIMER3_PARAMS.saltMonovalent;
|
|
67
72
|
|
|
68
73
|
// Adjust for divalent cations
|
|
@@ -84,7 +89,7 @@ function getEffectiveMonovalentConc() {
|
|
|
84
89
|
* @param {number} nnPairs - Number of nearest-neighbor pairs
|
|
85
90
|
* @returns {number} - Corrected entropy in cal/K·mol
|
|
86
91
|
*/
|
|
87
|
-
function applySaltCorrection(deltaS, nnPairs) {
|
|
92
|
+
function applySaltCorrection(deltaS: number, nnPairs: number): number {
|
|
88
93
|
const effectiveMono = getEffectiveMonovalentConc();
|
|
89
94
|
// SantaLucia (1998) salt correction
|
|
90
95
|
return deltaS + 0.368 * nnPairs * Math.log(effectiveMono / 1000);
|
|
@@ -96,7 +101,7 @@ function applySaltCorrection(deltaS, nnPairs) {
|
|
|
96
101
|
* @param {string} sequence - DNA sequence
|
|
97
102
|
* @returns {boolean} - True if valid
|
|
98
103
|
*/
|
|
99
|
-
export function isValidSequence(sequence) {
|
|
104
|
+
export function isValidSequence(sequence: string): boolean {
|
|
100
105
|
return /^[ATGCN]+$/.test(sequence);
|
|
101
106
|
}
|
|
102
107
|
|
|
@@ -107,16 +112,18 @@ export function isValidSequence(sequence) {
|
|
|
107
112
|
* @returns {number} - Melting temperature in Celsius
|
|
108
113
|
* @throws {Error} Invalid sequence or too short.
|
|
109
114
|
*/
|
|
110
|
-
export default function calculateSantaLuciaTm(
|
|
115
|
+
export default function calculateSantaLuciaTm(
|
|
116
|
+
sequence: string
|
|
117
|
+
): number | string {
|
|
111
118
|
// Convert to uppercase and validate
|
|
112
119
|
try {
|
|
113
|
-
|
|
120
|
+
const seq = sequence?.toUpperCase().trim();
|
|
114
121
|
|
|
115
|
-
if (!isValidSequence(
|
|
122
|
+
if (!isValidSequence(seq)) {
|
|
116
123
|
throw new Error("Invalid sequence: contains non-DNA characters");
|
|
117
124
|
}
|
|
118
125
|
|
|
119
|
-
if (
|
|
126
|
+
if (seq.length < 2) {
|
|
120
127
|
throw new Error("Sequence too short: minimum length is 2 bases");
|
|
121
128
|
}
|
|
122
129
|
|
|
@@ -124,8 +131,8 @@ export default function calculateSantaLuciaTm(sequence) {
|
|
|
124
131
|
let deltaS = 0; // cal/K·mol
|
|
125
132
|
|
|
126
133
|
// Calculate nearest-neighbor contributions
|
|
127
|
-
for (let i = 0; i <
|
|
128
|
-
const dinucleotide =
|
|
134
|
+
for (let i = 0; i < seq.length - 1; i++) {
|
|
135
|
+
const dinucleotide = seq.substring(i, i + 2);
|
|
129
136
|
|
|
130
137
|
// Skip if contains N
|
|
131
138
|
if (dinucleotide.includes("N")) {
|
|
@@ -140,28 +147,28 @@ export default function calculateSantaLuciaTm(sequence) {
|
|
|
140
147
|
}
|
|
141
148
|
|
|
142
149
|
// Add initiation parameters
|
|
143
|
-
const firstBase =
|
|
144
|
-
const lastBase =
|
|
150
|
+
const firstBase = seq[0];
|
|
151
|
+
const lastBase = seq[seq.length - 1];
|
|
145
152
|
|
|
146
153
|
// Terminal GC or AT initiation
|
|
147
154
|
if (firstBase === "G" || firstBase === "C") {
|
|
148
|
-
deltaH += SANTA_LUCIA_INIT
|
|
149
|
-
deltaS += SANTA_LUCIA_INIT
|
|
155
|
+
deltaH += SANTA_LUCIA_INIT["GC"].dH;
|
|
156
|
+
deltaS += SANTA_LUCIA_INIT["GC"].dS;
|
|
150
157
|
} else {
|
|
151
|
-
deltaH += SANTA_LUCIA_INIT
|
|
152
|
-
deltaS += SANTA_LUCIA_INIT
|
|
158
|
+
deltaH += SANTA_LUCIA_INIT["AT"].dH;
|
|
159
|
+
deltaS += SANTA_LUCIA_INIT["AT"].dS;
|
|
153
160
|
}
|
|
154
161
|
|
|
155
162
|
if (lastBase === "G" || lastBase === "C") {
|
|
156
|
-
deltaH += SANTA_LUCIA_INIT
|
|
157
|
-
deltaS += SANTA_LUCIA_INIT
|
|
163
|
+
deltaH += SANTA_LUCIA_INIT["GC"].dH;
|
|
164
|
+
deltaS += SANTA_LUCIA_INIT["GC"].dS;
|
|
158
165
|
} else {
|
|
159
|
-
deltaH += SANTA_LUCIA_INIT
|
|
160
|
-
deltaS += SANTA_LUCIA_INIT
|
|
166
|
+
deltaH += SANTA_LUCIA_INIT["AT"].dH;
|
|
167
|
+
deltaS += SANTA_LUCIA_INIT["AT"].dS;
|
|
161
168
|
}
|
|
162
169
|
|
|
163
170
|
// Apply salt correction
|
|
164
|
-
const nnPairs =
|
|
171
|
+
const nnPairs = seq.length - 1;
|
|
165
172
|
deltaS = applySaltCorrection(deltaS, nnPairs);
|
|
166
173
|
|
|
167
174
|
// Calculate Tm using: Tm = deltaH / (deltaS + R * ln(C/4))
|
|
@@ -4,10 +4,19 @@
|
|
|
4
4
|
* @author Nick Elsbree
|
|
5
5
|
* @author Zinovii Dmytriv (original author)
|
|
6
6
|
*/
|
|
7
|
+
|
|
8
|
+
interface CalculateTemperatureOptions {
|
|
9
|
+
type?: "breslauer" | "sugimoto" | "unified";
|
|
10
|
+
A?: number;
|
|
11
|
+
R?: number;
|
|
12
|
+
primerConc?: number;
|
|
13
|
+
monovalentCationConc?: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
7
16
|
const calcTmMethods = {
|
|
8
|
-
TABLE_BRESLAUER: "breslauer",
|
|
9
|
-
TABLE_SUGIMOTO: "sugimoto",
|
|
10
|
-
TABLE_UNIFIED: "unified",
|
|
17
|
+
TABLE_BRESLAUER: "breslauer" as const,
|
|
18
|
+
TABLE_SUGIMOTO: "sugimoto" as const,
|
|
19
|
+
TABLE_UNIFIED: "unified" as const,
|
|
11
20
|
|
|
12
21
|
A: -10.8, // Helix initiation for deltaS
|
|
13
22
|
R: 1.987, // Gas constant (cal/(K*mol)).
|
|
@@ -24,22 +33,29 @@ const calcTmMethods = {
|
|
|
24
33
|
* return - Temperature for the given sequence, in Celsius.
|
|
25
34
|
*/
|
|
26
35
|
calculateTemperature: function (
|
|
27
|
-
_sequence,
|
|
28
|
-
{
|
|
29
|
-
|
|
36
|
+
_sequence: string,
|
|
37
|
+
{
|
|
38
|
+
type,
|
|
39
|
+
A,
|
|
40
|
+
R,
|
|
41
|
+
primerConc,
|
|
42
|
+
monovalentCationConc
|
|
43
|
+
}: CalculateTemperatureOptions = {}
|
|
44
|
+
): number {
|
|
30
45
|
const sequence = (_sequence || "").toLowerCase();
|
|
31
46
|
if (typeof type === "undefined") {
|
|
32
47
|
// type = this.TABLE_SUGIMOTO ;
|
|
33
48
|
// type = this.TABLE_UNIFIED;
|
|
34
49
|
type = this.TABLE_BRESLAUER;
|
|
35
50
|
} else if (
|
|
36
|
-
type
|
|
37
|
-
type
|
|
38
|
-
type
|
|
51
|
+
type !== this.TABLE_BRESLAUER &&
|
|
52
|
+
type !== this.TABLE_UNIFIED &&
|
|
53
|
+
type !== this.TABLE_SUGIMOTO
|
|
39
54
|
) {
|
|
40
55
|
throw new Error("Invalid table type!");
|
|
41
56
|
}
|
|
42
57
|
|
|
58
|
+
/* eslint-disable no-param-reassign */
|
|
43
59
|
if (!A) {
|
|
44
60
|
A = this.A;
|
|
45
61
|
}
|
|
@@ -52,17 +68,23 @@ const calcTmMethods = {
|
|
|
52
68
|
if (!monovalentCationConc) {
|
|
53
69
|
monovalentCationConc = this.monovalentCationConc;
|
|
54
70
|
}
|
|
71
|
+
/* eslint-enable no-param-reassign */
|
|
55
72
|
|
|
56
73
|
const sequenceLength = sequence.length;
|
|
57
74
|
|
|
58
|
-
if (sequenceLength
|
|
75
|
+
if (sequenceLength === 0) {
|
|
59
76
|
return 0;
|
|
60
77
|
}
|
|
61
78
|
|
|
62
79
|
const deltaHTable = this.getDeltaHTable(type);
|
|
63
80
|
const deltaSTable = this.getDeltaSTable(type);
|
|
64
81
|
|
|
65
|
-
|
|
82
|
+
if (!deltaHTable || !deltaSTable) {
|
|
83
|
+
// Should not happen if type validation passes
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const neighbors: number[] = []; // List goes in order: aa, at, ac, ag, tt, ta, tc, tg, cc, ca, ct, cg, gg, ga, gt, gc
|
|
66
88
|
|
|
67
89
|
neighbors.push(this.calculateReps(sequence, "aa"));
|
|
68
90
|
neighbors.push(this.calculateNumberOfOccurrences(sequence, "at"));
|
|
@@ -88,6 +110,7 @@ const calcTmMethods = {
|
|
|
88
110
|
let sumDeltaS = 0.0;
|
|
89
111
|
|
|
90
112
|
for (let i = 0; i < 16; i++) {
|
|
113
|
+
// Safe access as neighbors and tables are 16-length
|
|
91
114
|
sumDeltaH = sumDeltaH + neighbors[i] * deltaHTable[i];
|
|
92
115
|
sumDeltaS = sumDeltaS + neighbors[i] * deltaSTable[i];
|
|
93
116
|
}
|
|
@@ -107,18 +130,18 @@ const calcTmMethods = {
|
|
|
107
130
|
* @param {String} type Algorithm to get table for.
|
|
108
131
|
* @return {Number[]} deltaH table for given algorithm.
|
|
109
132
|
*/
|
|
110
|
-
getDeltaHTable: function (type) {
|
|
111
|
-
if (type
|
|
133
|
+
getDeltaHTable: function (type: string): number[] | null {
|
|
134
|
+
if (type === this.TABLE_BRESLAUER) {
|
|
112
135
|
return [
|
|
113
136
|
9.1, 8.6, 6.5, 7.8, 9.1, 6.0, 5.6, 5.8, 11.0, 5.8, 7.8, 11.9, 11.0, 5.6,
|
|
114
137
|
6.5, 11.1
|
|
115
138
|
];
|
|
116
|
-
} else if (type
|
|
139
|
+
} else if (type === this.TABLE_SUGIMOTO) {
|
|
117
140
|
return [
|
|
118
141
|
8.0, 5.6, 6.5, 7.8, 8.0, 5.6, 5.6, 5.8, 10.9, 8.2, 6.6, 11.8, 10.9, 6.6,
|
|
119
142
|
9.4, 11.9
|
|
120
143
|
];
|
|
121
|
-
} else if (type
|
|
144
|
+
} else if (type === this.TABLE_UNIFIED) {
|
|
122
145
|
return [
|
|
123
146
|
7.9, 7.2, 8.4, 7.8, 7.9, 7.2, 8.2, 8.5, 8.0, 8.5, 7.8, 10.6, 8.0, 8.2,
|
|
124
147
|
8.4, 9.8
|
|
@@ -127,41 +150,6 @@ const calcTmMethods = {
|
|
|
127
150
|
return null;
|
|
128
151
|
}
|
|
129
152
|
},
|
|
130
|
-
// "AA/TT": -7.9, 7.9
|
|
131
|
-
// "AT/TA": -7.2, 7.2
|
|
132
|
-
// "AC/TG": -8.4, 8.4
|
|
133
|
-
// "AG/TC": -7.8, 7.8
|
|
134
|
-
// "TT/AA": -7.9, 7.9
|
|
135
|
-
// "TA/AT": -7.2, 7.2
|
|
136
|
-
// "TG/AC": -8.5, 8.2
|
|
137
|
-
// "TC/AG": -8.2, 8.5
|
|
138
|
-
// "CC/GG": -8.0, 8.0
|
|
139
|
-
// "CA/GT": -8.5, 8.5
|
|
140
|
-
// "CT/GA": -7.8, 7.8
|
|
141
|
-
// "CG/GC": -10.6, 10.6
|
|
142
|
-
// "GG/CC": -8.0, 8.0
|
|
143
|
-
// "GA/CT": -8.2, 8.2,
|
|
144
|
-
// "GT/CA": -8.4, 8.4
|
|
145
|
-
// "GC/CG": -9.8, 9.8
|
|
146
|
-
|
|
147
|
-
// aa, at, ac, ag, tt, ta, tc, tg, cc, ca, ct, cg, gg, ga, gt, gc
|
|
148
|
-
|
|
149
|
-
// "AA/TT": -22.2,22.2,
|
|
150
|
-
// "AT/TA": -20.4,20.4,
|
|
151
|
-
// "AC/TG": -22.4,22.4,
|
|
152
|
-
// "AG/TC": -21.0,21.0,
|
|
153
|
-
// "TT/AA": -22.2,22.2,
|
|
154
|
-
// "TA/AT": -21.3,21.3,
|
|
155
|
-
// "TC/AG": -22.2,22.2,
|
|
156
|
-
// "TG/AC": -22.7,22.7,
|
|
157
|
-
// "CC/GG": -19.9,19.9,
|
|
158
|
-
// "CA/GT": -22.7,22.7,
|
|
159
|
-
// "CT/GA": -21.0,21.0,
|
|
160
|
-
// "CG/GC": -27.2,27.2,
|
|
161
|
-
// "GG/CC": -19.9,19.9,
|
|
162
|
-
// "GT/CA": -22.4,22.2,
|
|
163
|
-
// "GA/CT": -22.2,22.4,
|
|
164
|
-
// "GC/CG": -24.4,24.4
|
|
165
153
|
|
|
166
154
|
/**
|
|
167
155
|
* @private
|
|
@@ -169,18 +157,18 @@ const calcTmMethods = {
|
|
|
169
157
|
* @param {String} type Algorithm to get table for.
|
|
170
158
|
* @return {Number[]} deltaS table for given algorithm.
|
|
171
159
|
*/
|
|
172
|
-
getDeltaSTable: function (type) {
|
|
173
|
-
if (type
|
|
160
|
+
getDeltaSTable: function (type: string): number[] | null {
|
|
161
|
+
if (type === this.TABLE_BRESLAUER) {
|
|
174
162
|
return [
|
|
175
163
|
24.0, 23.9, 17.3, 20.8, 24.0, 16.9, 13.5, 12.9, 26.6, 12.9, 20.8, 27.8,
|
|
176
164
|
26.6, 13.5, 17.3, 26.7
|
|
177
165
|
];
|
|
178
|
-
} else if (type
|
|
166
|
+
} else if (type === this.TABLE_SUGIMOTO) {
|
|
179
167
|
return [
|
|
180
168
|
21.9, 15.2, 17.3, 20.8, 21.9, 15.2, 13.5, 12.9, 28.4, 25.5, 23.5, 29.0,
|
|
181
169
|
28.4, 16.4, 25.5, 29.0
|
|
182
170
|
];
|
|
183
|
-
} else if (type
|
|
171
|
+
} else if (type === this.TABLE_UNIFIED) {
|
|
184
172
|
return [
|
|
185
173
|
22.2, 20.4, 22.4, 21.0, 22.2, 21.3, 22.2, 22.7, 19.9, 22.7, 21.0, 27.2,
|
|
186
174
|
19.9, 22.2, 22.4, 24.4
|
|
@@ -199,10 +187,10 @@ const calcTmMethods = {
|
|
|
199
187
|
* @param {String} target The string to search for.
|
|
200
188
|
* @return {Int} Number of occurrences of target in sequence, with repeats.
|
|
201
189
|
*/
|
|
202
|
-
calculateReps: function (sequence, target) {
|
|
190
|
+
calculateReps: function (sequence: string, target: string): number {
|
|
203
191
|
const sequenceLength = sequence.length;
|
|
204
192
|
|
|
205
|
-
if (sequenceLength
|
|
193
|
+
if (sequenceLength === 0) {
|
|
206
194
|
return 0;
|
|
207
195
|
}
|
|
208
196
|
|
|
@@ -213,7 +201,7 @@ const calcTmMethods = {
|
|
|
213
201
|
while (true) {
|
|
214
202
|
const foundSeq = sequence.indexOf(target, seqOffset);
|
|
215
203
|
|
|
216
|
-
if (foundSeq
|
|
204
|
+
if (foundSeq === -1) {
|
|
217
205
|
break;
|
|
218
206
|
}
|
|
219
207
|
|
|
@@ -235,10 +223,13 @@ const calcTmMethods = {
|
|
|
235
223
|
* @param {String} target The string to search for.
|
|
236
224
|
* @return {Int} Number of occurrences of target in sequence.
|
|
237
225
|
*/
|
|
238
|
-
calculateNumberOfOccurrences: function (
|
|
226
|
+
calculateNumberOfOccurrences: function (
|
|
227
|
+
sequence: string,
|
|
228
|
+
target: string
|
|
229
|
+
): number {
|
|
239
230
|
const sequenceLength = sequence.length;
|
|
240
231
|
|
|
241
|
-
if (sequenceLength
|
|
232
|
+
if (sequenceLength === 0) {
|
|
242
233
|
return 0;
|
|
243
234
|
}
|
|
244
235
|
|
|
@@ -5,8 +5,26 @@ import {
|
|
|
5
5
|
getRangeLength
|
|
6
6
|
} from "@teselagen/range-utils";
|
|
7
7
|
import getCutsitesFromSequence from "./getCutsitesFromSequence";
|
|
8
|
+
import { CutSite, DigestFragment, RestrictionEnzyme } from "./types";
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
// Explicitly define the params interface
|
|
11
|
+
export interface ComputeDigestFragmentsParams {
|
|
12
|
+
cutsites: CutSite[];
|
|
13
|
+
sequenceLength: number;
|
|
14
|
+
circular: boolean;
|
|
15
|
+
includeOverAndUnderHangs?: boolean;
|
|
16
|
+
computePartialDigest?: boolean;
|
|
17
|
+
computeDigestDisabled?: boolean;
|
|
18
|
+
computePartialDigestDisabled?: boolean;
|
|
19
|
+
selectionLayerUpdate?: (params: {
|
|
20
|
+
start: number;
|
|
21
|
+
end: number;
|
|
22
|
+
name: string;
|
|
23
|
+
}) => void;
|
|
24
|
+
updateSelectedFragment?: (id: string) => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function computeDigestFragments({
|
|
10
28
|
cutsites,
|
|
11
29
|
sequenceLength,
|
|
12
30
|
circular,
|
|
@@ -17,14 +35,17 @@ function computeDigestFragments({
|
|
|
17
35
|
computePartialDigestDisabled,
|
|
18
36
|
selectionLayerUpdate,
|
|
19
37
|
updateSelectedFragment
|
|
20
|
-
}) {
|
|
21
|
-
const fragments = [];
|
|
22
|
-
const overlappingEnzymes = [];
|
|
23
|
-
const pairs = [];
|
|
38
|
+
}: ComputeDigestFragmentsParams) {
|
|
39
|
+
const fragments: DigestFragment[] = [];
|
|
40
|
+
const overlappingEnzymes: DigestFragment[] = [];
|
|
41
|
+
const pairs: CutSite[][] = [];
|
|
24
42
|
|
|
25
|
-
const sortedCutsites = cutsites.
|
|
26
|
-
|
|
27
|
-
|
|
43
|
+
const sortedCutsites = cutsites.filter(
|
|
44
|
+
(
|
|
45
|
+
c
|
|
46
|
+
): c is CutSite & { topSnipPosition: number; bottomSnipPosition: number } =>
|
|
47
|
+
c.topSnipPosition != null && c.bottomSnipPosition != null
|
|
48
|
+
);
|
|
28
49
|
if (!circular && cutsites.length) {
|
|
29
50
|
sortedCutsites.push({
|
|
30
51
|
id: "seqTerm_" + shortid(),
|
|
@@ -33,6 +54,7 @@ function computeDigestFragments({
|
|
|
33
54
|
overhangBps: "",
|
|
34
55
|
topSnipPosition: 0,
|
|
35
56
|
bottomSnipPosition: 0,
|
|
57
|
+
overhangSize: 0, // Added to satisfy CutSite
|
|
36
58
|
upstreamTopSnip: 0,
|
|
37
59
|
upstreamBottomSnip: 0,
|
|
38
60
|
upstreamTopBeforeBottom: false,
|
|
@@ -43,21 +65,21 @@ function computeDigestFragments({
|
|
|
43
65
|
},
|
|
44
66
|
forward: true,
|
|
45
67
|
name: "Sequence_Terminus",
|
|
68
|
+
type: "START_OR_END_OF_SEQ",
|
|
46
69
|
restrictionEnzyme: {
|
|
47
|
-
name: "Sequence_Terminus"
|
|
70
|
+
name: "Sequence_Terminus",
|
|
71
|
+
site: "",
|
|
72
|
+
forwardRegex: "",
|
|
73
|
+
reverseRegex: ""
|
|
48
74
|
}
|
|
49
75
|
});
|
|
50
76
|
}
|
|
51
77
|
|
|
78
|
+
sortedCutsites.sort((a, b) => {
|
|
79
|
+
return a.topSnipPosition - b.topSnipPosition;
|
|
80
|
+
});
|
|
81
|
+
|
|
52
82
|
sortedCutsites.forEach((cutsite1, index) => {
|
|
53
|
-
if (computePartialDigest && !computePartialDigestDisabled) {
|
|
54
|
-
sortedCutsites.forEach((cs, index2) => {
|
|
55
|
-
if (index2 === index + 1 || index2 === 0) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
pairs.push([cutsite1, sortedCutsites[index2]]);
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
83
|
if (!computeDigestDisabled) {
|
|
62
84
|
pairs.push([
|
|
63
85
|
cutsite1,
|
|
@@ -66,36 +88,48 @@ function computeDigestFragments({
|
|
|
66
88
|
: sortedCutsites[0]
|
|
67
89
|
]);
|
|
68
90
|
}
|
|
91
|
+
if (computePartialDigest && !computePartialDigestDisabled) {
|
|
92
|
+
sortedCutsites.forEach((cs, index2) => {
|
|
93
|
+
// Filter out adjacent cutsites (standard digest handles these)
|
|
94
|
+
const isAdjacent =
|
|
95
|
+
index2 === index + 1 ||
|
|
96
|
+
(index === sortedCutsites.length - 1 && index2 === 0);
|
|
97
|
+
if (isAdjacent) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
pairs.push([cutsite1, sortedCutsites[index2]]);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
69
103
|
});
|
|
70
104
|
|
|
71
105
|
pairs.forEach(r => {
|
|
72
106
|
let [cut1, cut2] = r;
|
|
73
107
|
|
|
74
|
-
let start;
|
|
75
|
-
let end;
|
|
76
|
-
let size;
|
|
108
|
+
let start: number;
|
|
109
|
+
let end: number;
|
|
110
|
+
let size: number;
|
|
77
111
|
start = normalizePositionByRangeLength(
|
|
78
|
-
cut1.topSnipPosition
|
|
112
|
+
cut1.topSnipPosition!,
|
|
79
113
|
sequenceLength
|
|
80
114
|
);
|
|
81
115
|
end = normalizePositionByRangeLength(
|
|
82
|
-
cut2.topSnipPosition - 1,
|
|
116
|
+
cut2.topSnipPosition! - 1,
|
|
83
117
|
sequenceLength
|
|
84
118
|
);
|
|
85
119
|
size = getRangeLength({ start, end }, sequenceLength);
|
|
86
|
-
let overlapsSelf;
|
|
120
|
+
let overlapsSelf: boolean | undefined;
|
|
87
121
|
if (includeOverAndUnderHangs) {
|
|
88
122
|
const oldSize = size;
|
|
89
123
|
start = normalizePositionByRangeLength(
|
|
90
124
|
cut1.topSnipBeforeBottom
|
|
91
|
-
? cut1.topSnipPosition
|
|
92
|
-
: cut1.bottomSnipPosition
|
|
125
|
+
? cut1.topSnipPosition!
|
|
126
|
+
: cut1.bottomSnipPosition!,
|
|
93
127
|
sequenceLength
|
|
94
128
|
);
|
|
95
129
|
end = normalizePositionByRangeLength(
|
|
96
130
|
cut2.topSnipBeforeBottom
|
|
97
|
-
? cut2.bottomSnipPosition - 1
|
|
98
|
-
: cut2.topSnipPosition - 1,
|
|
131
|
+
? cut2.bottomSnipPosition! - 1
|
|
132
|
+
: cut2.topSnipPosition! - 1,
|
|
99
133
|
sequenceLength
|
|
100
134
|
);
|
|
101
135
|
size = getRangeLength({ start, end }, sequenceLength);
|
|
@@ -106,7 +140,7 @@ function computeDigestFragments({
|
|
|
106
140
|
}
|
|
107
141
|
}
|
|
108
142
|
|
|
109
|
-
let isFormedFromLinearEnd;
|
|
143
|
+
let isFormedFromLinearEnd: boolean | undefined;
|
|
110
144
|
if (cut1.name === "Sequence_Terminus") {
|
|
111
145
|
cut1 = cloneDeep(cut1);
|
|
112
146
|
isFormedFromLinearEnd = true;
|
|
@@ -119,13 +153,31 @@ function computeDigestFragments({
|
|
|
119
153
|
cut2.restrictionEnzyme.name = "Linear_Sequence_End";
|
|
120
154
|
}
|
|
121
155
|
|
|
156
|
+
// Add isOverhangIncludedInFragmentSize logic
|
|
157
|
+
cut1 = {
|
|
158
|
+
...cut1,
|
|
159
|
+
isOverhangIncludedInFragmentSize:
|
|
160
|
+
cut1.name !== "Linear_Sequence_Start" &&
|
|
161
|
+
cut1.name !== "Sequence_Terminus" &&
|
|
162
|
+
(cut1.overhangSize || 0) > 0 &&
|
|
163
|
+
!!cut1.topSnipBeforeBottom
|
|
164
|
+
};
|
|
165
|
+
cut2 = {
|
|
166
|
+
...cut2,
|
|
167
|
+
isOverhangIncludedInFragmentSize:
|
|
168
|
+
cut2.name !== "Linear_Sequence_End" &&
|
|
169
|
+
cut2.name !== "Sequence_Terminus" &&
|
|
170
|
+
(cut2.overhangSize || 0) > 0 &&
|
|
171
|
+
!cut2.topSnipBeforeBottom
|
|
172
|
+
};
|
|
173
|
+
|
|
122
174
|
const id = start + "-" + end + "-" + size + "-";
|
|
123
175
|
const name = `${cut1.restrictionEnzyme.name} -- ${cut2.restrictionEnzyme.name} ${size} bps`;
|
|
124
|
-
getRangeLength({ start, end }, sequenceLength);
|
|
176
|
+
// getRangeLength({ start, end }, sequenceLength);
|
|
125
177
|
|
|
126
178
|
fragments.push({
|
|
127
179
|
isFormedFromLinearEnd,
|
|
128
|
-
madeFromOneCutsite: cut1 === cut2,
|
|
180
|
+
madeFromOneCutsite: cut1.id === cut2.id,
|
|
129
181
|
start,
|
|
130
182
|
end,
|
|
131
183
|
size,
|
|
@@ -163,20 +215,24 @@ function computeDigestFragments({
|
|
|
163
215
|
};
|
|
164
216
|
}
|
|
165
217
|
|
|
166
|
-
function getDigestFragsForSeqAndEnzymes({
|
|
218
|
+
export function getDigestFragsForSeqAndEnzymes({
|
|
167
219
|
sequence,
|
|
168
220
|
circular,
|
|
169
221
|
enzymes,
|
|
170
222
|
includeOverAndUnderHangs
|
|
223
|
+
}: {
|
|
224
|
+
sequence: string;
|
|
225
|
+
circular: boolean;
|
|
226
|
+
enzymes: RestrictionEnzyme[];
|
|
227
|
+
includeOverAndUnderHangs?: boolean;
|
|
171
228
|
}) {
|
|
172
229
|
const cutsitesByName = getCutsitesFromSequence(sequence, circular, enzymes);
|
|
173
|
-
|
|
230
|
+
const digest = computeDigestFragments({
|
|
174
231
|
includeOverAndUnderHangs,
|
|
175
|
-
cutsites: flatMap(cutsitesByName),
|
|
232
|
+
cutsites: flatMap(cutsitesByName) as CutSite[],
|
|
176
233
|
sequenceLength: sequence.length,
|
|
177
234
|
circular
|
|
178
235
|
});
|
|
236
|
+
digest.fragments.sort((a, b) => b.size - a.size);
|
|
237
|
+
return digest;
|
|
179
238
|
}
|
|
180
|
-
|
|
181
|
-
export { computeDigestFragments };
|
|
182
|
-
export { getDigestFragsForSeqAndEnzymes };
|
package/src/{condensePairwiseAlignmentDifferences.js → condensePairwiseAlignmentDifferences.ts}
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export default function condensePairwiseAlignmentDifferences(
|
|
2
|
-
referenceSeq,
|
|
3
|
-
alignedSeq
|
|
4
|
-
) {
|
|
5
|
-
const overviewMinimapTrack = [];
|
|
2
|
+
referenceSeq: string,
|
|
3
|
+
alignedSeq: string
|
|
4
|
+
): string {
|
|
5
|
+
const overviewMinimapTrack: string[] = [];
|
|
6
6
|
const referenceSeqSplit = referenceSeq.toLowerCase().split("");
|
|
7
7
|
const alignedSeqSplit = alignedSeq.toLowerCase().split("");
|
|
8
8
|
const seqLength = alignedSeq.length;
|