peptide-score 2.3.14

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 (55) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +149 -0
  3. package/lib/src/allowNeutralLoss.d.ts +7 -0
  4. package/lib/src/allowNeutralLoss.d.ts.map +1 -0
  5. package/lib/src/allowNeutralLoss.js +25 -0
  6. package/lib/src/allowNeutralLoss.js.map +1 -0
  7. package/lib/src/aminoAcids.d.ts +29 -0
  8. package/lib/src/aminoAcids.d.ts.map +1 -0
  9. package/lib/src/aminoAcids.js +247 -0
  10. package/lib/src/aminoAcids.js.map +1 -0
  11. package/lib/src/chargePeptide.d.ts +2 -0
  12. package/lib/src/chargePeptide.d.ts.map +1 -0
  13. package/lib/src/chargePeptide.js +50 -0
  14. package/lib/src/chargePeptide.js.map +1 -0
  15. package/lib/src/digestPeptide.d.ts +2 -0
  16. package/lib/src/digestPeptide.d.ts.map +1 -0
  17. package/lib/src/digestPeptide.js +83 -0
  18. package/lib/src/digestPeptide.js.map +1 -0
  19. package/lib/src/generatePeptideFragments.d.ts +2 -0
  20. package/lib/src/generatePeptideFragments.d.ts.map +1 -0
  21. package/lib/src/generatePeptideFragments.js +89 -0
  22. package/lib/src/generatePeptideFragments.js.map +1 -0
  23. package/lib/src/getAA.d.ts +29 -0
  24. package/lib/src/getAA.d.ts.map +1 -0
  25. package/lib/src/getAA.js +21 -0
  26. package/lib/src/getAA.js.map +1 -0
  27. package/lib/src/index.d.ts +44 -0
  28. package/lib/src/index.d.ts.map +1 -0
  29. package/lib/src/index.js +74 -0
  30. package/lib/src/index.js.map +1 -0
  31. package/lib/src/isoElectricPoint.d.ts +10 -0
  32. package/lib/src/isoElectricPoint.d.ts.map +1 -0
  33. package/lib/src/isoElectricPoint.js +134 -0
  34. package/lib/src/isoElectricPoint.js.map +1 -0
  35. package/lib/src/sequenceToMF.d.ts +2 -0
  36. package/lib/src/sequenceToMF.d.ts.map +1 -0
  37. package/lib/src/sequenceToMF.js +99 -0
  38. package/lib/src/sequenceToMF.js.map +1 -0
  39. package/lib/src/splitPeptide.d.ts +2 -0
  40. package/lib/src/splitPeptide.d.ts.map +1 -0
  41. package/lib/src/splitPeptide.js +17 -0
  42. package/lib/src/splitPeptide.js.map +1 -0
  43. package/lib/tsconfig.build.tsbuildinfo +1 -0
  44. package/lib/tsconfig.test.tsbuildinfo +1 -0
  45. package/package.json +29 -0
  46. package/src/allowNeutralLoss.js +22 -0
  47. package/src/aminoAcids.js +244 -0
  48. package/src/chargePeptide.js +48 -0
  49. package/src/digestPeptide.js +87 -0
  50. package/src/generatePeptideFragments.js +89 -0
  51. package/src/getAA.js +18 -0
  52. package/src/index.js +37 -0
  53. package/src/isoElectricPoint.js +124 -0
  54. package/src/sequenceToMF.js +96 -0
  55. package/src/splitPeptide.js +13 -0
@@ -0,0 +1,48 @@
1
+ import { getAA } from './getAA';
2
+
3
+ // SOURCE: https://en.wikipedia.org/wiki/Amino_acid
4
+
5
+ export function chargePeptide(mf, options = {}) {
6
+ if (Array.isArray(mf)) {
7
+ for (let i = 0; i < mf.length; i++) {
8
+ mf[i] = chargeOnePeptide(mf[i], options);
9
+ }
10
+ return mf;
11
+ } else {
12
+ return chargeOnePeptide(mf, options);
13
+ }
14
+ }
15
+
16
+ function chargeOnePeptide(mf, options) {
17
+ const { pH = 0 } = options;
18
+ // we will allow to charge the peptide at a specific pH
19
+
20
+ // first amino acids (N-terminal)
21
+ if (mf.match(/^H[A-Z][a-z]{2}/)) {
22
+ let firstAA = mf.replace(/^H([A-Z][a-z]{2}).*/, '$1');
23
+ if (getAA(firstAA) && pH < getAA(firstAA).pKaN) {
24
+ mf = mf.replace(/^H([^+])/, 'H+H$1');
25
+ }
26
+ }
27
+
28
+ // last amino acids (C-terminal)
29
+ if (mf.match(/[A-Z][a-z]{2}OH$/)) {
30
+ let lastAA = mf.replace(/.*([A-Z][a-z]{2})OH$/, '$1');
31
+ if (getAA(lastAA) && pH > getAA(lastAA).pKaC) {
32
+ mf = mf.replace(/OH$/, 'O-');
33
+ }
34
+ }
35
+
36
+ // basic AA
37
+ if (pH < getAA('Arg').sc.pKa) mf = mf.replaceAll(/(Arg)(?!\()/g, '$1(H+)');
38
+ if (pH < getAA('His').sc.pKa) mf = mf.replaceAll(/(His)(?!\()/g, '$1(H+)');
39
+ if (pH < getAA('Lys').sc.pKa) mf = mf.replaceAll(/(Lys)(?!\()/g, '$1(H+)');
40
+
41
+ // acid AA
42
+ if (pH > getAA('Asp').sc.pKa) mf = mf.replaceAll(/(Asp)(?!\()/g, '$1(H-1-)');
43
+ if (pH > getAA('Glu').sc.pKa) mf = mf.replaceAll(/(Glu)(?!\()/g, '$1(H-1-)');
44
+
45
+ if (pH > getAA('Cys').sc.pKa) mf = mf.replaceAll(/(Cys)(?!\()/g, '$1(H-1-)');
46
+
47
+ return mf;
48
+ }
@@ -0,0 +1,87 @@
1
+ /*
2
+ Iotuibs:
3
+ * minMissed (default: 0)
4
+ * maxMissed (default: 0)
5
+ * minResidue: 0;
6
+ * maxResidue: infinity
7
+ * enzyme: chymotrypsin, trypsin, glucph4, glucph8, thermolysin, cyanogenbromide : Mandatory, no default value !
8
+ */
9
+
10
+ export function digestPeptide(sequence, options = {}) {
11
+ sequence = sequence.replace(/^H([^a-z])/, '$1').replace(/OH$/, '');
12
+ options.enzyme = options.enzyme || 'trypsin';
13
+ if (options.minMissed === undefined) options.minMissed = 0;
14
+ if (options.maxMissed === undefined) options.maxMissed = 0;
15
+ if (options.minResidue === undefined) options.minResidue = 0;
16
+ if (options.maxResidue === undefined) options.maxResidue = Number.MAX_VALUE;
17
+ let regexp = getRegexp(options.enzyme);
18
+ let fragments = sequence.replace(regexp, '$1 ').split(/ /).filter(Boolean);
19
+
20
+ {
21
+ let from = 0;
22
+ for (let i = 0; i < fragments.length; i++) {
23
+ let nbResidue = fragments[i]
24
+ .replaceAll(/([A-Z][a-z]{2})/g, ' $1')
25
+ .split(/ /)
26
+ .filter(Boolean).length;
27
+ fragments[i] = {
28
+ sequence: fragments[i],
29
+ nbResidue,
30
+ from,
31
+ to: from + nbResidue - 1,
32
+ };
33
+ from += nbResidue;
34
+ }
35
+ }
36
+
37
+ let results = [];
38
+
39
+ for (let i = 0; i < fragments.length - options.minMissed; i++) {
40
+ for (
41
+ let j = options.minMissed;
42
+ j <= Math.min(options.maxMissed, fragments.length - i - 1);
43
+ j++
44
+ ) {
45
+ let fragment = '';
46
+ let nbResidue = 0;
47
+ for (let k = i; k <= i + j; k++) {
48
+ fragment += fragments[k].sequence;
49
+ nbResidue += fragments[k].nbResidue;
50
+ }
51
+ let from = fragments[i].from + 1;
52
+ let to = fragments[i + j].to + 1;
53
+ if (
54
+ fragment &&
55
+ nbResidue >= options.minResidue &&
56
+ nbResidue <= options.maxResidue
57
+ ) {
58
+ results.push(`H${fragment}OH$D${from}>${to}`);
59
+ }
60
+ }
61
+ }
62
+
63
+ return results;
64
+ }
65
+
66
+ function getRegexp(enzyme) {
67
+ switch (enzyme.toLowerCase().replaceAll(/[^\da-z]/g, '')) {
68
+ case 'chymotrypsin':
69
+ return /(Phe|Tyr|Trp)(?!Pro)/g;
70
+ case 'trypsin':
71
+ return /(Lys|Arg)(?!Pro)/g;
72
+ case 'lysc':
73
+ return /(Lys)(?!Pro)/g;
74
+ case 'glucph4':
75
+ return /(Glu)(?!Pro|Glu)/g;
76
+ case 'glucph8':
77
+ return /(Asp|Glu)(?!Pro|Glu)/g;
78
+ case 'thermolysin': // N-term of Leu, Phe, Val, Ile, Ala, Met
79
+ return /()(?=Ile|Leu|Val|Ala|Met|Phe)/g;
80
+ case 'cyanogenbromide':
81
+ return /(Met)/g;
82
+ case 'any':
83
+ return /()(?=[A-Z][a-z]{2})/g;
84
+ default:
85
+ throw new Error(`Digestion enzyme: ${enzyme} is unknown`);
86
+ }
87
+ }
@@ -0,0 +1,89 @@
1
+ export function generatePeptideFragments(mf, options) {
2
+ if (options === undefined) {
3
+ options = {
4
+ a: false,
5
+ b: true,
6
+ c: false,
7
+ x: false,
8
+ y: true,
9
+ z: false,
10
+ i: false,
11
+ ya: false,
12
+ yb: false,
13
+ yc: false,
14
+ zc: false,
15
+ };
16
+ }
17
+ options.maxInternal = options.maxInternal || Number.MAX_VALUE;
18
+ options.minInternal = options.minInternal || 0;
19
+
20
+ let mfs = [];
21
+ // need to allow 0-9 to deal with neutral loss
22
+ let mfparts = mf
23
+ .replaceAll(/([\d)a-z])([A-Z][a-z](?=[a-z]))/g, '$1 $2')
24
+ .split(/ /);
25
+
26
+ let nTerm = '';
27
+ let cTerm = '';
28
+
29
+ if (mfparts[0].startsWith('(')) {
30
+ nTerm += mfparts[0];
31
+ mfparts = mfparts.splice(1);
32
+ }
33
+
34
+ if (mfparts.at(-1).includes('(')) {
35
+ cTerm += mfparts.at(-1).replace(/^[^()]*/, '');
36
+ mfparts[mfparts.length - 1] = mfparts.at(-1).replace(/\(.*/, '');
37
+ }
38
+
39
+ for (let i = 1; i < mfparts.length; i++) {
40
+ nTerm += mfparts[i - 1];
41
+ cTerm = mfparts[mfparts.length - i] + cTerm;
42
+ addNTerm(mfs, nTerm, i, options);
43
+ addCTerm(mfs, cTerm, i, options);
44
+ if (options.i) mfs.push(`${mfparts[i]}HC-1O-1(+1)$i:${mfparts[i]}`);
45
+
46
+ if (options.ya || options.yb || options.yc || options.zc) {
47
+ // we have double fragmentations
48
+ for (
49
+ let j = i + 1;
50
+ j < Math.min(mfparts.length, options.maxInternal + i + 1);
51
+ j++
52
+ ) {
53
+ let iTerm = '';
54
+ if (j - i >= options.minInternal) {
55
+ for (let k = i; k < j; k++) {
56
+ iTerm += mfparts[k];
57
+ }
58
+ addITerm(mfs, iTerm, mfparts.length - i, j, options);
59
+ }
60
+ }
61
+ }
62
+ }
63
+
64
+ // todo does this make sense ??? I think we should remote those 3 lines
65
+ if (mfs.length === 0) {
66
+ mfs = mfs.concat([mf]);
67
+ }
68
+
69
+ return mfs;
70
+ }
71
+
72
+ function addNTerm(mfs, nTerm, i, options) {
73
+ if (options.a) mfs.push(`${nTerm}C-1O-1(+1)$a${i}`);
74
+ if (options.b) mfs.push(`${nTerm}(+1)$b${i}`);
75
+ if (options.c) mfs.push(`${nTerm}NH3(+1)$c${i}`);
76
+ }
77
+
78
+ function addITerm(mfs, iTerm, i, j, options) {
79
+ if (options.ya) mfs.push(`H${iTerm}C-1O-1(+1)$a${j}y${i}`);
80
+ if (options.yb) mfs.push(`H${iTerm}(+1)$b${j}y${i}`);
81
+ if (options.yc) mfs.push(`H${iTerm}NH3(+1)$c${j}y${i}`);
82
+ if (options.zc) mfs.push(`N-1${iTerm}NH3(+1)$c${j}z${i}`);
83
+ }
84
+
85
+ function addCTerm(mfs, cTerm, i, options) {
86
+ if (options.x) mfs.push(`CO(+1)${cTerm}$x${i}`);
87
+ if (options.y) mfs.push(`H2(+1)${cTerm}$y${i}`);
88
+ if (options.z) mfs.push(`N-1H-1(+1)${cTerm}$z${i}`);
89
+ }
package/src/getAA.js ADDED
@@ -0,0 +1,18 @@
1
+ import { aminoAcids } from './aminoAcids';
2
+
3
+ export function getAA(code) {
4
+ if (code.length === 1) {
5
+ for (let i = 0; i < aminoAcids.length; i++) {
6
+ if (aminoAcids[i].aa1 === code) {
7
+ return aminoAcids[i];
8
+ }
9
+ }
10
+ }
11
+ if (code.length === 3) {
12
+ for (let i = 0; i < aminoAcids.length; i++) {
13
+ if (aminoAcids[i].aa3 === code) {
14
+ return aminoAcids[i];
15
+ }
16
+ }
17
+ }
18
+ }
package/src/index.js ADDED
@@ -0,0 +1,37 @@
1
+ import { aminoAcids } from './aminoAcids';
2
+ import * as IEP from './isoElectricPoint';
3
+ import { splitPeptide } from './splitPeptide.js';
4
+
5
+ export * from './allowNeutralLoss.js';
6
+ export * from './chargePeptide.js';
7
+ export * from './sequenceToMF.js';
8
+ export * from './generatePeptideFragments.js';
9
+ export * from './digestPeptide.js';
10
+ export * from './splitPeptide.js';
11
+
12
+ export function getInfo() {
13
+ return aminoAcids;
14
+ }
15
+
16
+ // sequence should be in the "right" format like HAlaGlyProOH
17
+
18
+ export function calculateIEP(sequence) {
19
+ let aas = splitPeptide(sequence);
20
+ let result = IEP.calculateIEP(aas);
21
+ return result;
22
+ }
23
+
24
+ export function calculateIEPChart(sequence) {
25
+ let aas = splitPeptide(sequence);
26
+ let result = IEP.calculateChart(aas);
27
+ return result;
28
+ }
29
+
30
+ export function getColorForIEP(iep) {
31
+ return IEP.getColor(iep);
32
+ }
33
+
34
+ export function calculateCharge(sequence, ph) {
35
+ let aas = splitPeptide(sequence);
36
+ return IEP.calculateCharge(aas, ph);
37
+ }
@@ -0,0 +1,124 @@
1
+ import { aminoAcids } from './aminoAcids';
2
+
3
+ // we will convert the data to an object to be much faster
4
+ let aaObject = {};
5
+ for (let i = 0; i < aminoAcids.length; i++) {
6
+ aaObject[aminoAcids[i].aa3] = aminoAcids[i];
7
+ }
8
+
9
+ export function calculateCharge(aas, pH = 7) {
10
+ let combined = combine(aas);
11
+ if (!combined) return;
12
+ let charge = calculateForPh(combined, pH);
13
+ return Math.round(charge * 1000) / 1000;
14
+ }
15
+
16
+ // this methods required an array of aas
17
+
18
+ export function calculateIEP(aas) {
19
+ let combined = combine(aas);
20
+ if (!combined) return;
21
+ let first = 0;
22
+ let last = 14;
23
+ let current = 14;
24
+ let previous = 0;
25
+ let currentCharge;
26
+ while (Math.abs(current - previous) > 0.0001) {
27
+ previous = current;
28
+ current = (last + first) / 2;
29
+ currentCharge = calculateForPh(combined, current);
30
+ if (currentCharge > 0) {
31
+ first = current;
32
+ } else if (currentCharge < 0) {
33
+ last = current;
34
+ } else {
35
+ previous = current;
36
+ }
37
+ }
38
+ return Math.round(current * 1000) / 1000;
39
+ }
40
+
41
+ export function calculateChart(aas) {
42
+ let combined = combine(aas);
43
+ if (!combined) return;
44
+ let y = [];
45
+ let x = [];
46
+ let yAbs = [];
47
+ for (let i = 0; i <= 14; i = i + 0.01) {
48
+ let charge = calculateForPh(combined, i);
49
+ x.push(i);
50
+ y.push(charge);
51
+ yAbs.push(Math.abs(charge));
52
+ }
53
+ combined.x = x;
54
+ combined.y = y;
55
+ combined.yAbs = yAbs;
56
+
57
+ return combined;
58
+ }
59
+
60
+ function calculateForPh(combined, pH) {
61
+ let total = 0;
62
+ total += 1 / (1 + 10 ** (pH - combined.first));
63
+ total += -1 / (1 + 10 ** (combined.last - pH));
64
+ for (let key in combined.acid) {
65
+ total += -combined.acid[key] / (1 + 10 ** (aaObject[key].sc.pKa - pH));
66
+ }
67
+ for (let key in combined.basic) {
68
+ total += combined.basic[key] / (1 + 10 ** (pH - aaObject[key].sc.pKa));
69
+ }
70
+ return total;
71
+ }
72
+
73
+ // we will combine the amino acids
74
+ function combine(aas) {
75
+ let combined = {};
76
+ if (aaObject[aas[0]]) {
77
+ combined.first = aaObject[aas[0]].pKaN;
78
+ } else {
79
+ return;
80
+ }
81
+ if (aaObject[aas.at(-1)]) {
82
+ combined.last = aaObject[aas.at(-1)].pKaC;
83
+ } else {
84
+ return;
85
+ }
86
+ combined.basic = {};
87
+ combined.acid = {};
88
+ for (let i = 0; i < aas.length; i++) {
89
+ let currentAA = aas[i];
90
+ if (!aaObject[currentAA]) return;
91
+ if (aaObject[currentAA].sc && aaObject[currentAA].sc.type) {
92
+ if (aaObject[currentAA].sc.type === 'positive') {
93
+ if (!combined.basic[currentAA]) {
94
+ combined.basic[currentAA] = 0;
95
+ }
96
+ combined.basic[currentAA]++;
97
+ } else if (aaObject[currentAA].sc.type === 'negative') {
98
+ if (!combined.acid[currentAA]) {
99
+ combined.acid[currentAA] = 0;
100
+ }
101
+ combined.acid[currentAA]++;
102
+ }
103
+ }
104
+ }
105
+ return combined;
106
+ }
107
+
108
+ /*
109
+ We can generate a color based on iep
110
+ 0 -> 7 means that at pH 7 it is charged negatively (blue)
111
+ 7 -> 14 means that at pH7 it is charged positively (red)
112
+ */
113
+ export function getColor(iep) {
114
+ if (iep < 7) {
115
+ if (iep < 3) iep = 3;
116
+ let white = Math.round(255 - (7 - iep) * (200 / 4));
117
+ return `rgb(${white},${white},255)`;
118
+ } else if (iep > 7) {
119
+ if (iep > 11) iep = 11;
120
+ let white = Math.round(255 - (iep - 7) * (200 / 4));
121
+ return `rgb(255,${white},${white})`;
122
+ }
123
+ return 'rgb(255,255,255)';
124
+ }
@@ -0,0 +1,96 @@
1
+ import { ensureUppercaseSequence } from 'mf-utilities';
2
+
3
+ import { aminoAcids } from './aminoAcids';
4
+
5
+ export function sequenceToMF(mf) {
6
+ if (mf === '') return '';
7
+ mf = ensureUppercaseSequence(mf);
8
+ // this function will check if it is a sequence of aa in 1 letter or 3 letters and convert them if it is the case
9
+ // it could be a multiline mf !
10
+ // if it is a multiline we could make some "tricks" ...
11
+
12
+ let newMF = mf;
13
+ // SEQRES 1 B 256 MET PRO VAL GLU ILE THR VAL LYS GLU LEU LEU GLU ALA
14
+ // SEQRES 2 B 256 GLY VAL HIS PHE GLY HIS GLU ARG LYS ARG TRP ASN PRO
15
+ // or
16
+ // MET PRO VAL GLU ILE THR VAL LYS GLU LEU LEU GLU ALA
17
+ // GLY VAL HIS PHE GLY HIS GLU ARG LYS ARG TRP ASN PRO
18
+ if (mf.search(/(?:[A-Z]{3} ){2}[A-Z]{3}/) > -1) {
19
+ // this is a PDB !
20
+ let tmpmf = mf.replaceAll(/[\n\r]+/g, ' ');
21
+ tmpmf = tmpmf.replaceAll(/(SEQRES|\d+| [A-Z] | [\dA-Z]{4-50})/g, '');
22
+ // we need to correct the uppercase / lowercase
23
+ let parts = tmpmf.split(' ');
24
+ newMF = 'H';
25
+ for (let i = 0; i < parts.length; i++) {
26
+ newMF += parts[i].slice(0, 1) + parts[i].slice(1).toLowerCase();
27
+ }
28
+ newMF += 'OH';
29
+ } else if (mf.includes('(') && isOneLetterCode(mf)) {
30
+ // we expect one-letter code with modification
31
+ newMF = '';
32
+ let nTerminal = 'H';
33
+ let cTerminal = 'OH';
34
+ let parenthesisCounter = 0;
35
+ for (let i = 0; i < mf.length; i++) {
36
+ let currentSymbol = mf[i];
37
+ if (
38
+ currentSymbol === '(' ||
39
+ currentSymbol === ')' ||
40
+ parenthesisCounter > 0
41
+ ) {
42
+ if (currentSymbol === '(') {
43
+ parenthesisCounter++;
44
+ if (i === 0) nTerminal = '';
45
+ }
46
+ if (currentSymbol === ')') {
47
+ parenthesisCounter--;
48
+ if (i === mf.length - 1) cTerminal = '';
49
+ }
50
+ newMF += currentSymbol;
51
+ continue;
52
+ }
53
+ newMF += convertAA1To3(currentSymbol);
54
+ }
55
+ newMF = nTerminal + newMF + cTerminal;
56
+ } else if (mf.search(/[A-Za-z][\da-z]/) === -1) {
57
+ // UNIPROT
58
+ // 370 380 390 400 410 420
59
+ //GFKPNLRKTF VSGLFRESCG AHFYRGVDVK PFYIKKPVDN LFALMLILNR LRGWGVVGGM
60
+ //
61
+ // 430 440 450 460 470 480
62
+ //SDPRLYKVWV RLSSQVPSMF FGGTDLAADY YVVSPPTAVS VYTKTPYGRL LADTRTSGFR
63
+ // We remove all the number, all the spaces, etc
64
+ newMF = `H${convertAA1To3(newMF.replaceAll(/[^A-Z]/g, ''))}OH`;
65
+ }
66
+
67
+ return newMF;
68
+ }
69
+
70
+ function convertAA1To3(mf) {
71
+ let newmf = '';
72
+ for (let i = 0; i < mf.length; i++) {
73
+ newmf += aa1To3(mf.charAt(i));
74
+ }
75
+ return newmf;
76
+ }
77
+
78
+ function aa1To3(code) {
79
+ for (let i = 0; i < aminoAcids.length; i++) {
80
+ if (aminoAcids[i].aa1 === code) {
81
+ return aminoAcids[i].aa3;
82
+ }
83
+ }
84
+ throw new Error(`Invalid 1 letter code: ${code}`);
85
+ }
86
+
87
+ // mf can contain as well parenthesis. We need to check if it is not yet a correct molecular formula
88
+ function isOneLetterCode(mf) {
89
+ let parenthesisLevel = 0;
90
+ for (let char of mf) {
91
+ if (parenthesisLevel === 0 && char.match(/[a-z]/)) return false;
92
+ if (char === '(') parenthesisLevel++;
93
+ if (char === ')') parenthesisLevel--;
94
+ }
95
+ return true;
96
+ }
@@ -0,0 +1,13 @@
1
+ export function splitPeptide(sequence) {
2
+ let aas = sequence.replaceAll(/([A-Z])/g, ' $1').split(/ /);
3
+ let begin = 0;
4
+ while (aas[begin] === '' || aas[begin] === 'H') {
5
+ begin++;
6
+ }
7
+ let end = aas.length - 1;
8
+ while (aas[end] === 'O' || aas[end] === 'H') {
9
+ end--;
10
+ }
11
+ aas = aas.slice(begin, end + 1);
12
+ return aas;
13
+ }