@teselagen/sequence-utils 0.3.41 → 0.3.42-beta.2
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 +765 -497
- package/index.d.ts +9 -5
- package/index.js +766 -498
- package/index.umd.cjs +765 -497
- 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.ts +22 -0
- 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 +8 -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.ts +24 -0
- 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 +99 -0
- package/threeLetterSequenceStringToAminoAcidMap.d.ts +11 -921
- package/tidyUpAnnotation.d.ts +13 -11
- package/tidyUpSequenceData.d.ts +18 -1
- package/types.d.ts +97 -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/adjustAnnotationsToInsert.js +0 -19
- 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/src/shiftAnnotationsByLen.js +0 -17
- 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
|
@@ -4,24 +4,44 @@ import {
|
|
|
4
4
|
ambiguous_rna_letters,
|
|
5
5
|
extended_protein_letters
|
|
6
6
|
} from "./bioData";
|
|
7
|
+
import { isFunction } from "lodash-es";
|
|
7
8
|
|
|
8
|
-
let allWarnings = [];
|
|
9
|
+
let allWarnings: string[] = [];
|
|
9
10
|
|
|
10
11
|
let makeToast = () => {
|
|
11
|
-
if (
|
|
12
|
-
window
|
|
12
|
+
if (
|
|
13
|
+
typeof window !== "undefined" &&
|
|
14
|
+
(window as unknown as { toastr: unknown }).toastr &&
|
|
15
|
+
allWarnings.length
|
|
16
|
+
) {
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
|
+
(window as any).toastr.warning(uniq(allWarnings).join("\n"));
|
|
13
19
|
}
|
|
14
20
|
allWarnings = [];
|
|
15
21
|
};
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
24
|
+
(makeToast as any) = debounce(makeToast, 200);
|
|
18
25
|
|
|
19
|
-
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
+
function showWarnings(warnings: any) {
|
|
20
28
|
allWarnings = allWarnings.concat(warnings);
|
|
21
|
-
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
+
(makeToast as any).cancel();
|
|
22
31
|
makeToast();
|
|
23
32
|
}
|
|
24
33
|
|
|
34
|
+
export interface FilterSequenceStringOptions {
|
|
35
|
+
additionalValidChars?: string;
|
|
36
|
+
isOligo?: boolean;
|
|
37
|
+
name?: string;
|
|
38
|
+
isProtein?: boolean;
|
|
39
|
+
isRna?: boolean;
|
|
40
|
+
getAcceptedInsertChars?: (options: FilterSequenceStringOptions) => string;
|
|
41
|
+
isMixedRnaAndDna?: boolean;
|
|
42
|
+
[key: string]: unknown;
|
|
43
|
+
}
|
|
44
|
+
|
|
25
45
|
export default function filterSequenceString(
|
|
26
46
|
sequenceString = "",
|
|
27
47
|
{
|
|
@@ -30,15 +50,23 @@ export default function filterSequenceString(
|
|
|
30
50
|
name,
|
|
31
51
|
isProtein,
|
|
32
52
|
isRna,
|
|
53
|
+
getAcceptedInsertChars,
|
|
33
54
|
isMixedRnaAndDna
|
|
34
|
-
} = {}
|
|
35
|
-
) {
|
|
36
|
-
const acceptedChars =
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
55
|
+
}: FilterSequenceStringOptions = {}
|
|
56
|
+
): [string, string[]] {
|
|
57
|
+
const acceptedChars = isFunction(getAcceptedInsertChars)
|
|
58
|
+
? getAcceptedInsertChars({
|
|
59
|
+
isOligo,
|
|
60
|
+
isProtein,
|
|
61
|
+
isRna,
|
|
62
|
+
isMixedRnaAndDna
|
|
63
|
+
})
|
|
64
|
+
: getAcceptedChars({
|
|
65
|
+
isOligo,
|
|
66
|
+
isProtein,
|
|
67
|
+
isRna,
|
|
68
|
+
isMixedRnaAndDna
|
|
69
|
+
});
|
|
42
70
|
const replaceChars = getReplaceChars({
|
|
43
71
|
isOligo,
|
|
44
72
|
isProtein,
|
|
@@ -47,10 +75,10 @@ export default function filterSequenceString(
|
|
|
47
75
|
});
|
|
48
76
|
|
|
49
77
|
let sanitizedVal = "";
|
|
50
|
-
const invalidChars = [];
|
|
78
|
+
const invalidChars: string[] = [];
|
|
51
79
|
const chars = `${acceptedChars}${additionalValidChars.split("").join("\\")}`;
|
|
52
|
-
const warnings = [];
|
|
53
|
-
const replaceCount = {};
|
|
80
|
+
const warnings: string[] = [];
|
|
81
|
+
const replaceCount: Record<string, number> = {};
|
|
54
82
|
sequenceString.split("").forEach(letter => {
|
|
55
83
|
const lowerLetter = letter.toLowerCase();
|
|
56
84
|
if (replaceChars && replaceChars[lowerLetter]) {
|
|
@@ -101,7 +129,7 @@ export function getAcceptedChars({
|
|
|
101
129
|
isProtein,
|
|
102
130
|
isRna,
|
|
103
131
|
isMixedRnaAndDna
|
|
104
|
-
} = {}) {
|
|
132
|
+
}: FilterSequenceStringOptions = {}) {
|
|
105
133
|
return isProtein
|
|
106
134
|
? `${extended_protein_letters.toLowerCase()}`
|
|
107
135
|
: isOligo
|
|
@@ -120,7 +148,7 @@ export function getReplaceChars({
|
|
|
120
148
|
isProtein,
|
|
121
149
|
isRna,
|
|
122
150
|
isMixedRnaAndDna
|
|
123
|
-
} = {}) {
|
|
151
|
+
}: FilterSequenceStringOptions = {}): Record<string, string> {
|
|
124
152
|
return isProtein
|
|
125
153
|
? {}
|
|
126
154
|
: // {".": "*"}
|
|
@@ -134,5 +162,7 @@ export function getReplaceChars({
|
|
|
134
162
|
{};
|
|
135
163
|
}
|
|
136
164
|
|
|
137
|
-
export const filterRnaString = (
|
|
138
|
-
|
|
165
|
+
export const filterRnaString = (
|
|
166
|
+
s: string,
|
|
167
|
+
o: FilterSequenceStringOptions
|
|
168
|
+
): string => filterSequenceString(s, { ...o, isRna: true })[0];
|
|
@@ -7,13 +7,21 @@
|
|
|
7
7
|
* @param {boolean} circular - Whether to treat the target sequence as circular (default: false)
|
|
8
8
|
* @returns {Array} - Array of objects containing { index, match, mismatchPositions }
|
|
9
9
|
*/
|
|
10
|
+
|
|
11
|
+
export interface ApproxMatch {
|
|
12
|
+
index: number;
|
|
13
|
+
match: string;
|
|
14
|
+
mismatchPositions: number[];
|
|
15
|
+
numMismatches: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
10
18
|
export default function findApproxMatches(
|
|
11
|
-
searchSeq,
|
|
12
|
-
targetSeq,
|
|
13
|
-
maxMismatches,
|
|
19
|
+
searchSeq: string,
|
|
20
|
+
targetSeq: string,
|
|
21
|
+
maxMismatches: number,
|
|
14
22
|
circular = false
|
|
15
|
-
) {
|
|
16
|
-
const matches = [];
|
|
23
|
+
): ApproxMatch[] {
|
|
24
|
+
const matches: ApproxMatch[] = [];
|
|
17
25
|
const lenA = searchSeq.length;
|
|
18
26
|
const lenB = targetSeq.length;
|
|
19
27
|
|
|
@@ -26,7 +34,7 @@ export default function findApproxMatches(
|
|
|
26
34
|
for (let i = 0; i < limit; i++) {
|
|
27
35
|
const window = targetSeqExtended.slice(i, i + lenA);
|
|
28
36
|
let mismatchCount = 0;
|
|
29
|
-
const mismatchPositions = [];
|
|
37
|
+
const mismatchPositions: number[] = [];
|
|
30
38
|
|
|
31
39
|
for (let j = 0; j < lenA; j++) {
|
|
32
40
|
if (searchSeq[j] !== window[j]) {
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import { normalizeRange } from "@teselagen/range-utils";
|
|
1
|
+
import { normalizeRange, Range } from "@teselagen/range-utils";
|
|
2
2
|
function findNearestRangeOfSequenceOverlapToPosition(
|
|
3
|
-
sequenceToSearch,
|
|
4
|
-
overlapSequence,
|
|
5
|
-
positionStart,
|
|
6
|
-
isLinear
|
|
7
|
-
) {
|
|
8
|
-
if (!positionStart) positionStart = 0;
|
|
3
|
+
sequenceToSearch: string,
|
|
4
|
+
overlapSequence: string,
|
|
5
|
+
positionStart = 0,
|
|
6
|
+
isLinear?: boolean
|
|
7
|
+
): Range | null {
|
|
9
8
|
if (sequenceToSearch.length < overlapSequence.length) {
|
|
10
9
|
return null;
|
|
11
10
|
}
|
|
12
11
|
const regex = new RegExp(overlapSequence, "ig");
|
|
13
|
-
let result;
|
|
14
|
-
let index;
|
|
12
|
+
let result: RegExpExecArray | null;
|
|
13
|
+
let index: number | undefined;
|
|
15
14
|
let distance = Infinity;
|
|
16
15
|
while (
|
|
17
16
|
(result = regex.exec(sequenceToSearch + (isLinear ? "" : sequenceToSearch)))
|
|
@@ -27,6 +26,11 @@ function findNearestRangeOfSequenceOverlapToPosition(
|
|
|
27
26
|
index = result.index;
|
|
28
27
|
distance = newDistance;
|
|
29
28
|
}
|
|
29
|
+
|
|
30
|
+
if (index === undefined) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
30
34
|
//index is the closest range start
|
|
31
35
|
return normalizeRange(
|
|
32
36
|
{
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import getOrfsFromSequence from "./getOrfsFromSequence
|
|
1
|
+
import getOrfsFromSequence, { Orf } from "./getOrfsFromSequence";
|
|
2
2
|
|
|
3
3
|
export default function findOrfsInPlasmid(
|
|
4
|
-
sequence,
|
|
5
|
-
circular,
|
|
6
|
-
minimumOrfSize,
|
|
7
|
-
useAdditionalOrfStartCodons,
|
|
8
|
-
isProteinOrOligo
|
|
9
|
-
) {
|
|
4
|
+
sequence: string,
|
|
5
|
+
circular: boolean,
|
|
6
|
+
minimumOrfSize: number,
|
|
7
|
+
useAdditionalOrfStartCodons: boolean,
|
|
8
|
+
isProteinOrOligo: boolean
|
|
9
|
+
): Orf[] {
|
|
10
10
|
if (isProteinOrOligo) {
|
|
11
11
|
// we do not find ORFs in protein/oligo sequences
|
|
12
12
|
return [];
|
|
@@ -27,5 +27,6 @@ export default function findOrfsInPlasmid(
|
|
|
27
27
|
circular: circular,
|
|
28
28
|
useAdditionalOrfStartCodons
|
|
29
29
|
});
|
|
30
|
+
|
|
30
31
|
return forwardOrfs.concat(reverseOrfs);
|
|
31
32
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
modulateRangeBySequenceLength,
|
|
3
|
-
flipContainedRange
|
|
3
|
+
flipContainedRange,
|
|
4
|
+
Range
|
|
4
5
|
} from "@teselagen/range-utils";
|
|
5
6
|
import { reduce, uniqBy } from "lodash-es";
|
|
6
7
|
import escapeStringRegexp from "escape-string-regexp";
|
|
@@ -8,11 +9,19 @@ import getAminoAcidStringFromSequenceString from "./getAminoAcidStringFromSequen
|
|
|
8
9
|
import { ambiguous_dna_values, extended_protein_values } from "./bioData";
|
|
9
10
|
import getReverseComplementSequenceString from "./getReverseComplementSequenceString";
|
|
10
11
|
|
|
12
|
+
export interface FindSequenceMatchesOptions {
|
|
13
|
+
searchReverseStrand?: boolean;
|
|
14
|
+
isCircular?: boolean;
|
|
15
|
+
isAmbiguous?: boolean;
|
|
16
|
+
isProteinSequence?: boolean;
|
|
17
|
+
isProteinSearch?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
11
20
|
export default function findSequenceMatches(
|
|
12
|
-
sequence,
|
|
13
|
-
searchString,
|
|
14
|
-
options = {}
|
|
15
|
-
) {
|
|
21
|
+
sequence: string,
|
|
22
|
+
searchString: string,
|
|
23
|
+
options: FindSequenceMatchesOptions = {}
|
|
24
|
+
): (Range & { bottomStrand?: boolean })[] {
|
|
16
25
|
let matches = findSequenceMatchesTopStrand(sequence, searchString, options);
|
|
17
26
|
const { searchReverseStrand } = options;
|
|
18
27
|
|
|
@@ -39,7 +48,11 @@ export default function findSequenceMatches(
|
|
|
39
48
|
return matches;
|
|
40
49
|
}
|
|
41
50
|
|
|
42
|
-
function findSequenceMatchesTopStrand(
|
|
51
|
+
function findSequenceMatchesTopStrand(
|
|
52
|
+
sequence: string,
|
|
53
|
+
searchString: string,
|
|
54
|
+
options: FindSequenceMatchesOptions = {}
|
|
55
|
+
): Range[] {
|
|
43
56
|
const { isCircular, isAmbiguous, isProteinSequence, isProteinSearch } =
|
|
44
57
|
options;
|
|
45
58
|
let searchStringToUse = escapeStringRegexp(searchString);
|
|
@@ -51,7 +64,10 @@ function findSequenceMatchesTopStrand(sequence, searchString, options = {}) {
|
|
|
51
64
|
);
|
|
52
65
|
} else {
|
|
53
66
|
//we're searching DNA
|
|
54
|
-
searchStringToUse = convertAmbiguousStringToRegex(
|
|
67
|
+
searchStringToUse = convertAmbiguousStringToRegex(
|
|
68
|
+
searchStringToUse,
|
|
69
|
+
false
|
|
70
|
+
);
|
|
55
71
|
}
|
|
56
72
|
}
|
|
57
73
|
if (!searchStringToUse) return []; //short circuit if nothing is actually being searched for (eg searching for "%%"")
|
|
@@ -86,11 +102,11 @@ function findSequenceMatchesTopStrand(sequence, searchString, options = {}) {
|
|
|
86
102
|
];
|
|
87
103
|
}
|
|
88
104
|
|
|
89
|
-
const ranges = [];
|
|
105
|
+
const ranges: Range[] = [];
|
|
90
106
|
sequencesToCheck.forEach(({ seqToCheck, offset }) => {
|
|
91
107
|
const reg = new RegExp(searchStringToUse, "ig");
|
|
92
|
-
let match;
|
|
93
|
-
let range;
|
|
108
|
+
let match: RegExpExecArray | null;
|
|
109
|
+
let range: Range;
|
|
94
110
|
/* eslint-disable no-cond-assign*/
|
|
95
111
|
|
|
96
112
|
while ((match = reg.exec(seqToCheck)) !== null) {
|
|
@@ -113,7 +129,7 @@ function findSequenceMatchesTopStrand(sequence, searchString, options = {}) {
|
|
|
113
129
|
});
|
|
114
130
|
}
|
|
115
131
|
|
|
116
|
-
function convertAmbiguousStringToRegex(string, isProtein) {
|
|
132
|
+
function convertAmbiguousStringToRegex(string: string, isProtein: boolean) {
|
|
117
133
|
// Search for a DNA subseq in sequence.
|
|
118
134
|
// use ambiguous values (like N = A or T or C or G, R = A or G etc.)
|
|
119
135
|
// searches only on forward strand
|
|
@@ -121,8 +137,10 @@ function convertAmbiguousStringToRegex(string, isProtein) {
|
|
|
121
137
|
string,
|
|
122
138
|
(acc, char) => {
|
|
123
139
|
const value = isProtein
|
|
124
|
-
? extended_protein_values[
|
|
125
|
-
|
|
140
|
+
? (extended_protein_values as Record<string, string>)[
|
|
141
|
+
char.toUpperCase()
|
|
142
|
+
]
|
|
143
|
+
: (ambiguous_dna_values as Record<string, string>)[char.toUpperCase()];
|
|
126
144
|
if (!value) return acc;
|
|
127
145
|
if (value.length === 1) {
|
|
128
146
|
acc += value;
|
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
import { generateRandomRange } from "@teselagen/range-utils";
|
|
2
2
|
import shortid from "shortid";
|
|
3
|
+
import { Annotation } from "./types";
|
|
3
4
|
|
|
4
5
|
function generateAnnotations(
|
|
5
|
-
numberOfAnnotationsToGenerate,
|
|
6
|
-
start,
|
|
7
|
-
end,
|
|
8
|
-
maxLength
|
|
9
|
-
) {
|
|
10
|
-
const result =
|
|
6
|
+
numberOfAnnotationsToGenerate: number,
|
|
7
|
+
start: number,
|
|
8
|
+
end: number,
|
|
9
|
+
maxLength: number
|
|
10
|
+
): Annotation[] {
|
|
11
|
+
const result: Annotation[] = [];
|
|
11
12
|
for (let i = 0; i < numberOfAnnotationsToGenerate; i++) {
|
|
12
13
|
const annotation = generateAnnotation(start, end, maxLength);
|
|
13
|
-
result
|
|
14
|
+
result.push(annotation);
|
|
14
15
|
}
|
|
15
16
|
return result;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
function generateAnnotation(
|
|
19
|
+
function generateAnnotation(
|
|
20
|
+
start: number,
|
|
21
|
+
end: number,
|
|
22
|
+
maxLength: number
|
|
23
|
+
): Annotation {
|
|
19
24
|
const range = generateRandomRange(start, end, maxLength);
|
|
20
25
|
return {
|
|
21
26
|
...range,
|
|
@@ -27,7 +32,7 @@ function generateAnnotation(start, end, maxLength) {
|
|
|
27
32
|
};
|
|
28
33
|
}
|
|
29
34
|
|
|
30
|
-
function getRandomInt(min, max) {
|
|
35
|
+
function getRandomInt(min: number, max: number): number {
|
|
31
36
|
return Math.floor(Math.random() * (max - min)) + min;
|
|
32
37
|
}
|
|
33
38
|
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
// this is throwing a weird eslint error
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
|
|
5
1
|
import generateAnnotations from "./generateAnnotations";
|
|
2
|
+
import { SequenceData } from "./types";
|
|
6
3
|
|
|
7
4
|
export default function generateSequenceData({
|
|
8
5
|
isProtein,
|
|
@@ -11,19 +8,28 @@ export default function generateSequenceData({
|
|
|
11
8
|
numParts,
|
|
12
9
|
numPrimers,
|
|
13
10
|
numTranslations
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
}: {
|
|
12
|
+
isProtein?: boolean;
|
|
13
|
+
sequenceLength?: number;
|
|
14
|
+
numFeatures?: number;
|
|
15
|
+
numParts?: number;
|
|
16
|
+
numPrimers?: number;
|
|
17
|
+
numTranslations?: number;
|
|
18
|
+
} = {}): SequenceData {
|
|
19
|
+
const proteinSequence = isProtein
|
|
20
|
+
? generateSequence(sequenceLength, true)
|
|
21
|
+
: "";
|
|
22
|
+
const sequence = !isProtein ? generateSequence(sequenceLength) : "";
|
|
17
23
|
|
|
18
24
|
return {
|
|
19
25
|
circular: isProtein ? false : Math.random() > 0.5,
|
|
20
|
-
name: "p-" + Math.floor(Math.random * 100),
|
|
26
|
+
name: "p-" + Math.floor(Math.random() * 100),
|
|
21
27
|
description: "",
|
|
22
|
-
isProtein,
|
|
28
|
+
isProtein: !!isProtein,
|
|
23
29
|
sequence,
|
|
24
30
|
proteinSequence,
|
|
25
31
|
translations: isProtein
|
|
26
|
-
?
|
|
32
|
+
? []
|
|
27
33
|
: generateAnnotations(
|
|
28
34
|
numTranslations || 5,
|
|
29
35
|
0,
|
|
@@ -37,7 +43,7 @@ export default function generateSequenceData({
|
|
|
37
43
|
sequenceLength / 3
|
|
38
44
|
),
|
|
39
45
|
primers: isProtein
|
|
40
|
-
?
|
|
46
|
+
? []
|
|
41
47
|
: generateAnnotations(numPrimers || 10, 0, sequenceLength - 1, 50),
|
|
42
48
|
parts: generateAnnotations(
|
|
43
49
|
numParts || 10,
|
|
@@ -50,9 +56,9 @@ export default function generateSequenceData({
|
|
|
50
56
|
|
|
51
57
|
// export default tidyUpSequenceData(exampleData)
|
|
52
58
|
|
|
53
|
-
function generateSequence(m = 9, isProtein) {
|
|
59
|
+
function generateSequence(m = 9, isProtein?: boolean): string {
|
|
54
60
|
let s = "";
|
|
55
|
-
const r = isProtein ? "" : "gatc";
|
|
61
|
+
const r = isProtein ? "ACDEFGHIKLMNPQRSTVWY" : "gatc"; // Added explicit protein string instead of empty string default behavior
|
|
56
62
|
for (let i = 0; i < m; i++) {
|
|
57
63
|
s += r.charAt(Math.floor(Math.random() * r.length));
|
|
58
64
|
}
|
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
// seqReads should be an array of objects [{name, seq, pos, cigar}, {name, seq, pos, cigar}, ...]
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
|
|
3
|
+
export interface SeqRead {
|
|
4
|
+
name: string;
|
|
5
|
+
seq: string;
|
|
6
|
+
pos: number;
|
|
7
|
+
cigar: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface InsertionInfo {
|
|
11
|
+
bpPos: number;
|
|
12
|
+
number: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default function getAllInsertionsInSeqReads(
|
|
16
|
+
seqReads: SeqRead[]
|
|
17
|
+
): InsertionInfo[] {
|
|
18
|
+
const allInsertionsInSeqReads: InsertionInfo[] = [];
|
|
4
19
|
seqReads.forEach(seqRead => {
|
|
5
20
|
// split cigar string at M, D, or I (match, deletion, or insertion), e.g. ["2M", "3I", "39M", "3D"...]
|
|
6
21
|
const splitSeqRead = seqRead.cigar.match(/([0-9]*[MDI])/g);
|
|
7
22
|
|
|
23
|
+
if (!splitSeqRead) return;
|
|
24
|
+
|
|
8
25
|
for (let componentI = 0; componentI < splitSeqRead.length; componentI++) {
|
|
9
26
|
if (splitSeqRead[componentI].slice(-1) === "I") {
|
|
10
27
|
let bpPosOfInsertion = seqRead.pos;
|
|
@@ -2,7 +2,8 @@ import {
|
|
|
2
2
|
translateRange,
|
|
3
3
|
getSequenceWithinRange,
|
|
4
4
|
flipContainedRange,
|
|
5
|
-
isPositionWithinRange
|
|
5
|
+
isPositionWithinRange,
|
|
6
|
+
Range
|
|
6
7
|
} from "@teselagen/range-utils";
|
|
7
8
|
import revComp from "./getReverseComplementSequenceString";
|
|
8
9
|
import getAA from "./getAminoAcidFromSequenceTriplet";
|
|
@@ -21,7 +22,11 @@ import proteinAlphabet from "./proteinAlphabet";
|
|
|
21
22
|
* @property {Number} basesRead The number of bases read
|
|
22
23
|
* @property {Number[]} codonPositions The positions of the codon bases in the sequenceString
|
|
23
24
|
*/
|
|
24
|
-
function getNextTriplet(
|
|
25
|
+
function getNextTriplet(
|
|
26
|
+
index: number,
|
|
27
|
+
sequenceString: string,
|
|
28
|
+
exonRange: Range[]
|
|
29
|
+
) {
|
|
25
30
|
let triplet = "";
|
|
26
31
|
let internalIndex;
|
|
27
32
|
// Positions of codons relative to the coding sequence start
|
|
@@ -29,7 +34,7 @@ function getNextTriplet(index, sequenceString, exonRange) {
|
|
|
29
34
|
const codonPositions = [];
|
|
30
35
|
|
|
31
36
|
// A function to check if a base is within an exon
|
|
32
|
-
const isBaseInExon = baseIndex =>
|
|
37
|
+
const isBaseInExon = (baseIndex: number) =>
|
|
33
38
|
exonRange.some(r =>
|
|
34
39
|
isPositionWithinRange(baseIndex, r, sequenceString.length, true, false)
|
|
35
40
|
);
|
|
@@ -74,10 +79,10 @@ function getNextTriplet(index, sequenceString, exonRange) {
|
|
|
74
79
|
* @property {Object[]} exonRange Array of ranges of the sequenceString that contains the positions of bases corresponding to exons.
|
|
75
80
|
*/
|
|
76
81
|
function getTranslatedSequenceProperties(
|
|
77
|
-
originalSequenceString,
|
|
78
|
-
forward,
|
|
79
|
-
optionalSubrangeRange,
|
|
80
|
-
isProteinSequence
|
|
82
|
+
originalSequenceString: string,
|
|
83
|
+
forward: boolean,
|
|
84
|
+
optionalSubrangeRange: Range | null,
|
|
85
|
+
isProteinSequence: boolean
|
|
81
86
|
) {
|
|
82
87
|
const originalSequenceStringLength = isProteinSequence
|
|
83
88
|
? originalSequenceString.length * 3
|
|
@@ -90,7 +95,7 @@ function getTranslatedSequenceProperties(
|
|
|
90
95
|
sequenceString = getSequenceWithinRange(
|
|
91
96
|
optionalSubrangeRange,
|
|
92
97
|
originalSequenceString
|
|
93
|
-
);
|
|
98
|
+
) as string;
|
|
94
99
|
translationRange.start = optionalSubrangeRange.start;
|
|
95
100
|
translationRange.end = optionalSubrangeRange.end;
|
|
96
101
|
}
|
|
@@ -106,8 +111,8 @@ function getTranslatedSequenceProperties(
|
|
|
106
111
|
// TODO: what to do with protein if this is true?
|
|
107
112
|
const absoluteExonRange =
|
|
108
113
|
!isProteinSequence &&
|
|
109
|
-
|
|
110
|
-
|
|
114
|
+
optionalSubrangeRange &&
|
|
115
|
+
optionalSubrangeRange.locations
|
|
111
116
|
? optionalSubrangeRange.locations
|
|
112
117
|
: [translationRange];
|
|
113
118
|
const exonRange = absoluteExonRange.map(range => {
|
|
@@ -148,10 +153,10 @@ function getTranslatedSequenceProperties(
|
|
|
148
153
|
*
|
|
149
154
|
*/
|
|
150
155
|
function positionInCdsToPositionInMainSequence(
|
|
151
|
-
index,
|
|
152
|
-
forward,
|
|
153
|
-
translationRange,
|
|
154
|
-
mainSequenceLength
|
|
156
|
+
index: number,
|
|
157
|
+
forward: boolean,
|
|
158
|
+
translationRange: Range,
|
|
159
|
+
mainSequenceLength: number
|
|
155
160
|
) {
|
|
156
161
|
let outputRange = translateRange(
|
|
157
162
|
{ start: index, end: index },
|
|
@@ -181,10 +186,10 @@ function positionInCdsToPositionInMainSequence(
|
|
|
181
186
|
}]
|
|
182
187
|
*/
|
|
183
188
|
export default function getAminoAcidDataForEachBaseOfDna(
|
|
184
|
-
originalSequenceString,
|
|
185
|
-
forward,
|
|
186
|
-
optionalSubrangeRange,
|
|
187
|
-
isProteinSequence
|
|
189
|
+
originalSequenceString: string,
|
|
190
|
+
forward: boolean,
|
|
191
|
+
optionalSubrangeRange: Range | null,
|
|
192
|
+
isProteinSequence: boolean
|
|
188
193
|
) {
|
|
189
194
|
if (!originalSequenceString) {
|
|
190
195
|
return [];
|
|
@@ -215,7 +220,8 @@ export default function getAminoAcidDataForEachBaseOfDna(
|
|
|
215
220
|
if (isProteinSequence) {
|
|
216
221
|
codonPositionsInCDS = [0, 1, 2].map(i => index + i);
|
|
217
222
|
basesRead = 3;
|
|
218
|
-
|
|
223
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
224
|
+
aminoAcid = (proteinAlphabet as any)[sequenceString[index / 3].toUpperCase()];
|
|
219
225
|
} else {
|
|
220
226
|
// Get the triplet of DNA bases
|
|
221
227
|
const {
|
|
@@ -241,13 +247,13 @@ export default function getAminoAcidDataForEachBaseOfDna(
|
|
|
241
247
|
// What should the codon range be if it comprises intron bases?
|
|
242
248
|
const codonRange = forward
|
|
243
249
|
? {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
250
|
+
start: absoluteCodonPositions[0],
|
|
251
|
+
end: absoluteCodonPositions[codonPositionsInCDS.length - 1]
|
|
252
|
+
}
|
|
247
253
|
: {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
254
|
+
start: absoluteCodonPositions[codonPositionsInCDS.length - 1],
|
|
255
|
+
end: absoluteCodonPositions[0]
|
|
256
|
+
};
|
|
251
257
|
|
|
252
258
|
// Iterate over the positions read
|
|
253
259
|
let positionInCodon = 0;
|
|
@@ -256,11 +262,11 @@ export default function getAminoAcidDataForEachBaseOfDna(
|
|
|
256
262
|
const sequenceIndex = codonPositionsInCDS.includes(posInCds)
|
|
257
263
|
? absoluteCodonPositions[codonPositionsInCDS.indexOf(posInCds)]
|
|
258
264
|
: positionInCdsToPositionInMainSequence(
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
265
|
+
posInCds,
|
|
266
|
+
forward,
|
|
267
|
+
translationRange,
|
|
268
|
+
originalSequenceStringLength
|
|
269
|
+
);
|
|
264
270
|
if (codonPositionsInCDS.includes(posInCds)) {
|
|
265
271
|
aminoAcidDataForEachBaseOfDNA.push({
|
|
266
272
|
aminoAcid,
|
|
@@ -4,19 +4,24 @@ import degenerateDnaToAminoAcidMap from "./degenerateDnaToAminoAcidMap";
|
|
|
4
4
|
|
|
5
5
|
//tnrtodo: expand the threeLetterSequenceStringToAminoAcidMap mappings to include RNA characters.
|
|
6
6
|
//currently stop bps aren't all mapped!
|
|
7
|
-
export default function getAminoAcidFromSequenceTriplet(
|
|
7
|
+
export default function getAminoAcidFromSequenceTriplet(
|
|
8
|
+
sequenceString: string
|
|
9
|
+
) {
|
|
8
10
|
sequenceString = sequenceString.toLowerCase();
|
|
9
11
|
if (sequenceString.length !== 3) {
|
|
10
12
|
throw new Error("must pass a string of length 3");
|
|
11
13
|
}
|
|
12
|
-
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15
|
+
const aa = (threeLetterSequenceStringToAminoAcidMap as any)[sequenceString];
|
|
13
16
|
if (aa) {
|
|
14
17
|
return aa;
|
|
15
18
|
}
|
|
16
19
|
const letter =
|
|
17
|
-
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
(degenerateDnaToAminoAcidMap as any)[
|
|
18
22
|
sequenceString.replace("x", "n") //replace x's with n's as those are equivalent dna chars
|
|
19
23
|
] || "x";
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
+
return (proteinAlphabet as any)[letter.toUpperCase()];
|
|
22
27
|
}
|
package/src/{getAminoAcidStringFromSequenceString.js → getAminoAcidStringFromSequenceString.ts}
RENAMED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import getAminoAcidDataForEachBaseOfDna from "./getAminoAcidDataForEachBaseOfDna";
|
|
2
|
+
import { AminoAcidData } from "./types";
|
|
2
3
|
|
|
3
4
|
export default function getAminoAcidStringFromSequenceString(
|
|
4
|
-
sequenceString,
|
|
5
|
-
{ doNotExcludeAsterisk } = {}
|
|
6
|
-
) {
|
|
5
|
+
sequenceString: string,
|
|
6
|
+
options: { doNotExcludeAsterisk?: boolean } = {}
|
|
7
|
+
): string {
|
|
8
|
+
const { doNotExcludeAsterisk } = options;
|
|
7
9
|
const aminoAcidsPerBase = getAminoAcidDataForEachBaseOfDna(
|
|
8
10
|
sequenceString,
|
|
9
|
-
true
|
|
11
|
+
true,
|
|
12
|
+
null,
|
|
13
|
+
false
|
|
10
14
|
);
|
|
11
|
-
const aaArray = [];
|
|
15
|
+
const aaArray: string[] = [];
|
|
12
16
|
let aaString = "";
|
|
13
|
-
aminoAcidsPerBase.forEach((aa, index) => {
|
|
17
|
+
aminoAcidsPerBase.forEach((aa: AminoAcidData, index: number) => {
|
|
14
18
|
if (!aa.fullCodon) {
|
|
15
19
|
return;
|
|
16
20
|
}
|
|
@@ -18,10 +22,13 @@ export default function getAminoAcidStringFromSequenceString(
|
|
|
18
22
|
if (
|
|
19
23
|
!doNotExcludeAsterisk &&
|
|
20
24
|
index >= aminoAcidsPerBase.length - 3 &&
|
|
21
|
-
aa.aminoAcid
|
|
25
|
+
aa.aminoAcid?.value === "*"
|
|
22
26
|
) {
|
|
23
27
|
return;
|
|
24
28
|
}
|
|
29
|
+
if (aa.aminoAcidIndex === null || !aa.aminoAcid) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
25
32
|
aaArray[aa.aminoAcidIndex] = aa.aminoAcid.value;
|
|
26
33
|
});
|
|
27
34
|
aaString = aaArray.join("");
|