From f2730a1d80e7f1031002ab105c3345cc550f421d Mon Sep 17 00:00:00 2001 From: MariaLukina Date: Sun, 8 Oct 2023 12:17:26 +0700 Subject: [PATCH 01/12] update README file --- README.md | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 196 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f3e345c..3734079 100644 --- a/README.md +++ b/README.md @@ -1 +1,196 @@ -# Junior_Bioinformatic_tool \ No newline at end of file +# My junior biochemical tool +This package for junior bioinformaticians is designed to work with nucleotide and amino acid sequences and FASTQ files, and consists of three parts. Each module `amino_acid_tools`, `dna_rna_tools` and `fastq_filtration` presents its own possibilities for sequence processing. + +# `amino_acids_tools` +This tool is designed to work with amino acid sequences consisting of _22 proteinogenic amino acid_ residues (including pyrrolizine and selenocysteine) recorded in a standard one-letter format. It is not intended to process sequences with post-translational and other amino acid modifications + +## Usage +You call the `amino_acid_tools` function, which takes as input an arbitrary number of arguments with amino-acid sequences (str), as well as the name of the procedure to be executed (it is always the last argument, str). After that the command performs the specified action on all the given sequences. If one sequence is submitted, a string with the result is returned. If several sequences are submitted, a list of strings is returned. +Input sequences can contain both uppercase and lowercase letters, but the last argument with the function name must correspond to the listed functions. + + +## Options +The following options for aminoacid sequence processing are available at the moment: + +- **molecular_weight**: calculate the molecular weight of the amino acid chain in Da, according to the average amino acid residues molecular masses rounded to 1 or 2 decimal places. +- **three_letter_code**: converts standard single letter translations to three letter translations +- **show_length**: count the overall number of amino acids in the given +- **sequence folding**: count the number of amino acids characteristic separately for alpha helixes and beta sheets,and give out what will be the structure of the protein more. This function has been tested on proteins such as 2M3X, 6DT4 (PDB ID) and MHC, CRP. The obtained results corresponded to reality. +- **seq_charge**: evaluates the overall charge of the aminoacid chain in neutral aqueous solution (pH = 7), according to the pKa of amino acid side chains, lysine, pyrrolizine and arginine contribute +1, while asparagine and glutamic amino acids contribute -1. The total charge of a protein is evaluated as positive, negative, or neutral as the sum of these contributions + +### Remarks +If sequense contains symbols differ from IUPAC 1-letter code for 22 proteinogenic amino acids, +the result *for this sequence* will be `'unexpected symbols in sequence'` regardless of function +If action is not in the function the message `'unexpected action'` will occur + +## Examples +Below is an example of processing an amino acid sequence for different input data +```Python +amino_acid_tools('DNA', 'molecular_weight') +``` +Output: 300.28 + +```Python +amino_acid_tools('DNA', 'russco', 'LOLkEk', 'azaz', 'three_letter_code') +``` +Output: ['AspAsnAla', 'ArgSecSerSerCysPyl', 'LeuPylLeuLysGluLys', 'unexpected symbols in sequence'] + +```Python +amino_acid_tools('DNA', 'russco', 'LOLkEk', 'azaz', 'letter_code') +``` +ValueError: Unexpected action + +### Using the function for molecular weight calculation + +```Python +amino_acid_tools('EGVIMSELKLK', 'PLPKvelPPDFVD', 'DVIGISILGKEV', 'molecular_weight') +``` + +Input: 'EGVIMSELKLK', 'PLPKvelPPDFVD', 'DVIGISILGKEV', 'molecular_weight' +Output: '[1228.66, 1447.8400000000001, 1224.6399999999999]' + +### Using the function to convert one-letter translations to three-letter translations + +```Python +amino_acid_tools('EGVIMSELKLK', 'PLPKvelPPDFVD', 'DVIGISILGKEV', 'three_letter_code') +``` + +Input: 'EGVIMSELKLK', 'PLPKvelPPDFVD', 'DVIGISILGKEV', 'three_letter_code' +Output: '['GluGlyValIleMetSerGluLeuLysLeuLys', 'ProLeuProLysValGluLeuProProAspPheValAsp', 'AspValIleGlyIleSerIleLeuGlyLysGluVal']' + +### Using the function to counts the number of amino acids in the given sequence + +```Python +amino_acid_tools('EGVIMSELKLK', 'PLPKvelPPDFVD', 'DVIGISILGKEV', 'show_length') +``` + +Input: 'EGVIMSELKLK', 'PLPKvelPPDFVD', 'DVIGISILGKEV', 'show_length' +Output: '[11, 13, 12]' + +### Using the function to determine the predominant secondary structure + +```Python +amino_acid_tools('EGVIMSELKLK', 'PLPKvelPPDFVD', 'DVIGISILGKEV', 'folding') +``` +Input: 'EGVIMSELKLK', 'PLPKvelPPDFVD', 'DVIGISILGKEV', 'folding' +Output: '['alfa_helix', 'equally', 'equally']' + +### Using the function to estimate relative charge + +```Python +amino_acid_tools('EGVIMSELKLK', 'PLPKvelPPDFVD', 'DVIGISILGKEV', 'seq_charge') +``` + +Input: 'EGVIMSELKLK', 'PLPKvelPPDFVD', 'DVIGISILGKEV', 'seq_charge' +Output: '['neutral', 'negative', 'negative']' + +# `DNA_RNA_tools` + +This program is designed to work with nucleic acid sequences. We expect RNA and DNA chains in the standard NNNNNNNN form, without phosphate groups, in uppercase or lowercase letters + +### Usage +You call the `dna_rna_tools` function, which takes as input anumber of arguments with amino-acid sequences (str), as well as the name of the procedure to be executed (it is always the last argument, str). + +The nucleotide sequence can consist of both uppercase and lowercase letters. +Input example: +```Python +dna_rna_tools('GCGGT','auccuc','GCTatGc','complement') +``` + +### Functions: +Folowing options are avaliable now: + + - **complement:** makes complement sequence to seq + - **reverse**: reverses sequence, (from 5'-3' to 3' -5' there or back) + - **reverse_complement**: makes complement sequence and reverse it + - **transcribe**: make transcript of DNA sequence. in the case of RNA + sequence, no changes will be returned + +*Returns:* +If one sequence is supplied, a string with the result is returned. +If several are submitted, a list of strings is returned. + +#### Remarks +If seq contains both U(u) and T(t) the result *for this sequence* will be `"U and T in one seq"` regardless of function + +If seq contains symbols differ from standardized oligonucleotide notation, the result *for this sequence* will be `'unexpected symbols in sequence'` regardless of function +If action is not in the function the message `'unexpected action'` will occur + +### Examples: +```Python +dna_rna_tools('ATTC', 'CGcGc', 'AZA', 'atuc', 'Au', 'transcribe') +``` +Output: ['AUUC', 'CGcGc', 'unexpected symbols in sequence', 'T and U in one seq', 'Au'] + + +```Python +dna_rna_tools('ATTC', 'CGcGc', 'AZA', 'atuc', 'Au', 'revese') +``` +ValueError: Unexpected action + +```Python +dna_rna_tools('UuCG','complement') +``` +Output: 'AaGC' + +# `FASTQ_filtration tool` + +This function provides you the opportunity to filter the FASTQ list to select sequences according to requirements on three parameters: length, GC composition, and quality of the reed + +### Usage +It is required to input the list of sequences in dictionary format, as well as values for filtering parameters: interval by GC-composition, interval by sequence length, threshold value of average quality of reed +Input example: +```Python +fastq_filtration(seqs, gc_bounds=(20, 40), length_bounds=(0, 2 *8), quality_treshold=10) +``` + +#### Filtering parameters + + - seqs: dictionary of FASTQ sequences *{name: (sequence, quality)}* + - **gc_bounds:** interval for the of acceptable GC content, in %, *Default + value = (0,100)* + - **length_bounds**: interval for the of acceptable sequense length in + number of nucleotide, *Default value = (2,2**32)* + - **quality_treshold**: threshold value for average quality per nucleotide + (phred33 scale), *Default value = 0* + + +### Result: +New dictionary consists of selected sequences after 3-step filtration +#### Remarks +After running without specifying the filtering parameters, all sequences will be be selected as appropriate +You also can specify only the upper limit for GC-content and length filtering + +### Examples + +```Python +d = {'a': ('atcaaa', '@@@@@@'), 'b': ('gcc', '@@!'), 'c': ('ga', '!!'), 'd': ('ga', '@@')} +``` +```Python +fastq_filtration(d) +``` +Output: {'a': ('atcaaa', '@@@@@@'), 'b': ('gcc', '@@!'), 'c': ('ga', '!!'), 'd': ('ga', '@@')} +No filtration with default values + +```Python +fastq_filtration(d, 40, (0, 3), 10) +``` +Output: {} + +```Python +fastq_filtration(d, 50, (0, 7), 10) +``` +Output: {'a': ('atcaaa', '@@@@@@'), 'd': ('ga', '@@')} + +```Python +fastq_filtration(d, 50, (0, 7), 0) +``` +Output: {'a': ('atcaaa', '@@@@@@'), 'c': ('ga', '!!'), 'd': ('ga', '@@')} + + +##### Contacts +Maria Lukina +maria.v.luk@gmail.com + + + From ff831602d69d526d79616908aa8c0a0f8be9bf3c Mon Sep 17 00:00:00 2001 From: MariaLukina Date: Sun, 8 Oct 2023 12:32:11 +0700 Subject: [PATCH 02/12] Add tool_for_bioinformatics main script --- tool_for_bioinformatics.py | 141 +++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 tool_for_bioinformatics.py diff --git a/tool_for_bioinformatics.py b/tool_for_bioinformatics.py new file mode 100644 index 0000000..b69ce31 --- /dev/null +++ b/tool_for_bioinformatics.py @@ -0,0 +1,141 @@ +import modules.nucleic_acids_functions as na +import modules.fastq_filters as ff +import modules.amino_acids_functions as aa +NUCLEOTIDES = {'U', 'A', 'g', 't', 'G', 'T', 'a', 'c', 'C', 'u'} +AMINO_ACIDS = {'M', 'O', 'v', 'D', 'f', 'N', 'c', 'A', 'R', 'W', 'I', 'm', 'L', 's', 'H', 'q', 'w', 'V', 'n', 'i', + 'g', 'F', 'S', 'e', 'l', 'U', 'P', 'Q', 'K', 'Y', 'u', 'y', 'd', 'h', 'k', 'r', 't', 'G', 'o', 'E', + 'p', 'T', 'C', 'a'} + + +def dna_rna_tools(*args: str): + """ + Performs functions for working with poly- and oligonucleotide sequences. + + Parameters: + The function must accept a number of nucleotide sequences (str) as input, + the last variable must be the function (str) you want to execute. + The nucleotide sequence can consist of both uppercase and lowercase letters. + Input example: + dna_rna_tools('GCGGT','auccuc','GCTatGc','complement') + Function: + complement: makes complement sequence to seq + reverse: reverses sequence, (from 5'-3' to 3' -5' there or back) + reverse_complement: makes complement sequence and reverse it + transcribe: make transcript of DNA sequence. in the case of RNA sequence, no changes will be returned + Returns: + If one sequence is supplied, a string with the result is returned. + If several are submitted, a list of strings is returned. + Depending on the function performed, the following returns will occur: + complement: (str) or (list) complement sequence to seq + reverse: (str) or (list) reversed sequence to seq + reverse_complement: (str) or (list) complement and reversed sequence + transcribe (str) or (list): transcript of DNA sequence. + in the case of RNA sequence, no changes will be returned, + If seq contains both U(u) and T(t) the result for this str will be + "U and T in one seq" regardless of function + If seq contains symbols differ from standardized oligonucleotide notation, the result will be + 'unexpected symbols in sequence' regardless of function + If action is not in the function the message 'unexpected action' will occur + """ + *seqs, action = args + result = list() + for seq in seqs: + if not set(seq).issubset(NUCLEOTIDES): + result.append('unexpected symbols in sequence') + elif (('U' in seq) or ('u' in seq)) and (('T' in seq) or ('t' in seq)): + result.append('T and U in one seq') + else: + if action == 'reverse': + result.append(na.reverse(seq)) + elif action == 'complement': + result.append(na.complement(seq)) + elif action == 'transcribe': + result.append(na.transcribe(seq)) + elif action == 'reverse_complement': + result.append(na.reverse_complement(seq)) + else: + raise ValueError("unexpected action") + if len(result) == 1: + result = result[0] + return result + + +def amino_acid_tools(*args: str): + """ + Performs functions for working with protein sequences. + + Parameters: + The function must accept an unlimited number of protein sequences (str) as input, + the last variable must be the function (str) you want to execute. + The amino acid sequence can consist of both uppercase and lowercase letters. + Input example: + amino_acid_tools('PLPKVEL','VDviRIkLQ','PPDFGKT','folding') + Function: + molecular_weight: calculates molecular weight of the amino acid chain + three_letter_code: converts single letter translations to three letter translations + length: counts the number of amino acids in the given sequence + folding: counts the number of amino acids characteristic separately for alpha helixes and beta sheets, + and gives out what will be the structure of the protein more + seq_charge: evaluates the overall charge of the aminoacid chain in neutral aqueous solution (pH = 7) + + Returns: + If one sequence is supplied, a string with the result is returned. + If several are submitted, a list of strings is returned. + Depending on the function performed, the following returns will occur: + molecular_weight (int) or (list): amino acid sequence molecular weight number or list of numbers + three_letter_code (str) or (list): translated sequence from one-letter in three-letter code + length (int) or (list): integer number of amino acid residues + folding (str) or (list): 'alpha_helix', if there are more alpha helices + 'beta_sheet', if there are more beta sheets + 'equally', if the probability of alpha spirals and beta sheets are the same + seq_charge(str) or (list): "positive", "negative" or "neutral" + If seq contains symbols differ from IUPAC 1letter code for 22 proteinogenic amino acids, + the result for this sequence will be 'unexpected symbols in sequence' regardless of function + If action is not in the function the message 'unexpected action' will occur + """ + *seqs, function = args + d_of_functions = {'molecular_weight': aa.molecular_weight, + 'three_letter_code': aa.three_letter_code, + 'length': aa.length, + 'folding': aa.folding, + 'seq_charge': aa.seq_charge} + answer = [] + if function not in d_of_functions.keys(): + raise ValueError("unexpected action") + for sequence in seqs: + if not set(sequence).issubset(AMINO_ACIDS): + answer.append('unexpected symbols in sequence') + else: + answer.append(d_of_functions[function](sequence)) + if len(answer) == 1: + return answer[0] + else: + return answer + + +def fastq_filtration(seqs, gc_bounds=(0, 100), length_bounds=(0, 2 ** 32), quality_treshold=0) -> dict: + """ + This function provides you the opportunity to filter the FASTQ list to select sequences + that fit requirements on three parameters: length, GC composition, and quality of the reed + :parameters + seqs: (dict) dictionary of FASTQ sequences {name: (sequence, quality)} + gc_bounds: (tuple or or float) interval for the of acceptable GC content, in % + length_bounds: (tuple or int) interval for the of acceptable sequence length in number of nucleotide + quality_treshold: (float) threshold value for average quality per nucleotide (phred33 scale) + :return: (dict) new dictionary consists of selected sequences after 3-step filtration + """ + if type(gc_bounds) == float or type(gc_bounds) == int: + gc_bounds_both_side = (0, gc_bounds) + else: + gc_bounds_both_side = gc_bounds + if type(length_bounds) == int: + length_bounds_both_side = (0, length_bounds) + else: + length_bounds_both_side = length_bounds + good_seqs = ff.filter_length(ff.filter_quality(ff.filter_gc(seqs, gc_bounds_both_side), quality_treshold), + length_bounds_both_side) + return good_seqs + + +res = amino_acid_tools('DNA', 'ussc', 'LOLkEk', 'alal', 'seq_charge') +print(res) \ No newline at end of file From 4235fdd8192d946ae5c1c092b47f31b37401d762 Mon Sep 17 00:00:00 2001 From: MariaLukina Date: Sun, 8 Oct 2023 12:33:40 +0700 Subject: [PATCH 03/12] Add directory modules with functions for sequenses --- modules/amino_acids_functions.py | 96 ++++++++++++++++++++++++++++++ modules/fastq_filters.py | 62 +++++++++++++++++++ modules/nucleic_acids_functions.py | 58 ++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 modules/amino_acids_functions.py create mode 100644 modules/fastq_filters.py create mode 100644 modules/nucleic_acids_functions.py diff --git a/modules/amino_acids_functions.py b/modules/amino_acids_functions.py new file mode 100644 index 0000000..876ab09 --- /dev/null +++ b/modules/amino_acids_functions.py @@ -0,0 +1,96 @@ +NAMES = {'A': 'Ala', 'R': 'Arg', 'N': 'Asn', 'D': 'Asp', 'C': 'Cys', 'E': 'Glu', 'Q': 'Gln', 'G': 'Gly', 'H': 'His', + 'I': 'Ile', 'L': 'Leu', 'K': 'Lys', 'M': 'Met', 'F': 'Phe', 'P': 'Pro', 'S': 'Ser', 'T': 'Thr', 'W': 'Trp', + 'Y': 'Tyr', 'V': 'Val', 'U': 'Sec', 'O': 'Pyl', 'a': 'Ala', 'r': 'Arg', 'n': 'Asn', 'd': 'Asp', 'c': 'Cys', + 'e': 'Glu', 'q': 'Gln', 'g': 'Gly', 'h': 'His', 'i': 'Ile', 'l': 'Leu', 'k': 'Lys', 'm': 'Met', 'f': 'Phe', + 'p': 'Pro', 's': 'Ser', 't': 'Thr', 'w': 'Trp', 'y': 'Tyr', 'v': 'Val', 'u': 'Sec', 'o': 'Pyl'} +MASSES = {'A': 71.08, 'R': 156.2, 'N': 114.1, 'D': 115.1, 'C': 103.1, 'E': 129.1, 'Q': 128.1, 'G': 57.05, 'H': 137.1, + 'I': 113.2, 'L': 113.2, 'K': 128.2, 'M': 131.2, 'F': 147.2, 'P': 97.12, 'S': 87.08, 'T': 101.1, 'W': 186.2, + 'Y': 163.2, 'V': 99.13, 'U': 168.05, 'O': 255.3, 'a': 71.08, 'r': 156.2, 'n': 114.1, 'd': 115.1, 'c': 103.1, + 'e': 129.1, 'q': 128.1, 'g': 57.05, 'h': 137.1, 'i': 113.2, 'l': 113.2, 'k': 128.2, 'm': 131.2, 'f': 147.2, + 'p': 97.12, 's': 87.08, 't': 101.1, 'w': 186.2, 'y': 163.2, 'v': 99.13, 'u': 168.05, 'o': 255.3} + + +def molecular_weight(seq: str) -> float: + """ + Function calculates molecular weight of the amino acid chain + Parameters: + seq (str): each letter refers to one-letter coded proteinogenic amino acids + Returns: + (float) Molecular weight of tge given amino acid chain in Da + """ + m = 0 + for acid in seq: + m += MASSES[acid] + return m + + +def three_letter_code(seq: str) -> str: + """ + Function converts single letter translations to three letter translations + Parameters: + seq (str): each letter refers to one-letter coded proteinogenic amino acids + Returns: + (str) translated in three-letter code + """ + recording = seq.maketrans(NAMES) + return seq.translate(recording) + + +def length(seq: str) -> int: + """ + Function counts the number of amino acids in the given sequence + Parameters: + seq (str): amino acid sequence + Returns: + (int): integer number of amino acid residues + """ + return len(seq) + + +def folding(seq: str) -> str: + """ + Counts the number of amino acids characteristic separately for alpha helixes and beta sheets, + and gives out what will be the structure of the protein more. + This function has been tested on proteins such as 2M3X, 6DT4 (PDB ID) and MHC, CRP. + The obtained results corresponded to reality. + Parameters: + seq (str): amino acid sequence + Returns: + (str): overcoming structure ('alfa_helix', 'beta_sheet', 'equally') + """ + alfa_helix = ['A', 'E', 'L', 'M', 'G', 'Y', 'S', 'a', 'e', 'l', 'm', 'g', 'y', 's'] + beta_sheet = ['Y', 'F', 'W', 'T', 'V', 'I', 'y', 'f', 'w', 't', 'v', 'i'] + alfa_helix_counts = 0 + beta_sheet_counts = 0 + for amino_acid in seq: + if amino_acid in alfa_helix: + alfa_helix_counts += 1 + elif amino_acid in beta_sheet: + beta_sheet_counts += 1 + if alfa_helix_counts > beta_sheet_counts: + return 'alfa_helix' + elif alfa_helix_counts < beta_sheet_counts: + return 'beta_sheet' + elif alfa_helix_counts == beta_sheet_counts: + return 'equally' + + +def seq_charge(seq: str) -> str: + """ + Function evaluates the overall charge of the aminoacid chain in neutral aqueous solution (pH = 7) + Parameters: + seq (str): amino acid sequence of proteinogenic amino acids + Returns: + (str): "positive", "negative" or "neutral" + """ + aminoacid_charge = {'R': 1, 'D': -1, 'E': -1, 'K': 1, 'O': 1, 'r': 1, 'd': -1, 'e': -1, 'k': 1, 'o': 1} + charge = 0 + for aminoacid in seq: + if aminoacid in aminoacid_charge.keys(): + charge += aminoacid_charge[aminoacid] + if charge > 0: + return 'positive' + elif charge < 0: + return 'negative' + else: + return 'neutral' diff --git a/modules/fastq_filters.py b/modules/fastq_filters.py new file mode 100644 index 0000000..84226c0 --- /dev/null +++ b/modules/fastq_filters.py @@ -0,0 +1,62 @@ +def gc_content(seq: str) -> float: + """ + Supporting function + Function counts GC-content in sequence, and returns result in % + Parameters: + seq (str): oligo- and polynucleotide sequence + Returns: + (float): % of GC-content + """ + n = 0 + for nucl in seq: + if nucl == 'c' or nucl == 'g' or nucl == 'C' or nucl == 'G': + n += 1 + return 100 * n / len(seq) + + +def filter_gc(seqs: dict, gc_bounds_both_side=(0, 100)) -> dict: + """ + This function selects sequences with the GC content of your interest + :parameters: + seqs: dictionary of FASTQ sequences {name: (sequence, quality)} + gc_bound: interval for the of acceptable GC content, in % + :return:(dict) new dictionary consists of selected sequences + """ + d_new = {} + for key, params in seqs.items(): + if gc_bounds_both_side[1] >= gc_content(params[0]) >= gc_bounds_both_side[0]: + d_new[key] = (params[0], params[1]) + return d_new + + +def filter_length(seqs: dict, length_bounds_both_side=(0, 2 ** 32)) -> dict: + """ + This function selects sequences with the length of your interest + :parameters: + seqs: dictionary of FASTQ sequences {name: (sequence, quality)} + length_bound: interval for the of acceptable sequense length in number of nucleotide + :return:(dict) new dictionary consists of selected sequences + """ + d_new = {} + for key, params in seqs.items(): + if length_bounds_both_side[1] >= len(params[0]) >= length_bounds_both_side[0]: + d_new[key] = (params[0], params[1]) + return d_new + + +def filter_quality(seqs: dict, quality_treshold=0) -> dict: + """ + This function selects FASTQ sequences with appropriate average nucleotide read quality + parameters: + seqs: dictionary of FASTQ sequences {name: (sequence, quality)} + quality_treshold: threshold value for average quality per nucleotide (phred33 scale) + :return:(dict) new dictionary consists of selected sequences + """ + d_new = {} + for key, params in seqs.items(): + quality_sum = 0 + for n in params[1]: + quality_sum += ord(n) - 33 + if quality_sum / len(params[1]) >= quality_treshold: + d_new[key] = (params[0], params[1]) + return d_new diff --git a/modules/nucleic_acids_functions.py b/modules/nucleic_acids_functions.py new file mode 100644 index 0000000..26638f4 --- /dev/null +++ b/modules/nucleic_acids_functions.py @@ -0,0 +1,58 @@ +DICT_COMPLEMENT_DNA = {'A': 'T', 'C': 'G', 'T': 'A', 'G': 'C', 'a': 't', 'c': 'g', 't': 'a', 'g': 'c'} +DICT_COMPLEMENT_RNA = {'A': 'U', 'C': 'G', 'U': 'A', 'G': 'C', 'a': 'u', 'c': 'g', 'u': 'a', 'g': 'c'} +DICT_TRANSCRIPTION = {'A': 'A', 'C': 'C', 'T': 'U', 'G': 'G', 'a': 'a', 'c': 'c', 't': 'u', 'g': 'g'} + + +def complement(seq: str) -> str: + """ + Function return complement sequence to sec + Parameters: + seq (str): oligo- and polynucleotide sequence + Returns: + (str): oligo- and polynucleotide sequence + """ + if ('U' in seq) or ('u' in seq): + complementary_rna = seq.maketrans(DICT_COMPLEMENT_RNA) + modified_seq = seq.translate(complementary_rna) + else: + complementary_dna = seq.maketrans(DICT_COMPLEMENT_DNA) + modified_seq = seq.translate(complementary_dna) + return modified_seq + + +def transcribe(seq: str) -> str: + """ + Function return transcript of DNA sequence, if the case of RNA sequence, no changes will be returned + Parameters: + seq (str): oligo- and polynucleotide sequence + Returns: + (str): oligo- and polynucleotide sequence + """ + if ('U' in seq) or ('u' in seq): + modified_seq = seq + else: + transcribe_dna = seq.maketrans(DICT_TRANSCRIPTION) + modified_seq = seq.translate(transcribe_dna) + return modified_seq + + +def reverse(seq: str) -> str: + """ + Function return reversed sequence, (from 5'-3' to 3' -5' there or back) + Parameters: + seq (str): oligo- and polynucleotide sequence + Returns: + (str): oligo- and polynucleotide sequence + """ + return seq[::-1] + + +def reverse_complement(seq: str) -> str: + """ + Function makes complement sequence and reverse it, (from 5'-3' to 3' -5' there or back) + Parameters: + seq (str): oligo- and polynucleotide sequence + Returns: + (str): oligo- and polynucleotide sequence + """ + return complement(seq)[::-1] From 61a6eb50facdeae9de2f3a7f9bcf43f5e77d0c3c Mon Sep 17 00:00:00 2001 From: MariaLukina Date: Sun, 8 Oct 2023 12:40:43 +0700 Subject: [PATCH 04/12] correct tool_for_bioinformatics file --- tool_for_bioinformatics.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tool_for_bioinformatics.py b/tool_for_bioinformatics.py index b69ce31..3e04aca 100644 --- a/tool_for_bioinformatics.py +++ b/tool_for_bioinformatics.py @@ -135,7 +135,3 @@ def fastq_filtration(seqs, gc_bounds=(0, 100), length_bounds=(0, 2 ** 32), quali good_seqs = ff.filter_length(ff.filter_quality(ff.filter_gc(seqs, gc_bounds_both_side), quality_treshold), length_bounds_both_side) return good_seqs - - -res = amino_acid_tools('DNA', 'ussc', 'LOLkEk', 'alal', 'seq_charge') -print(res) \ No newline at end of file From 7ff376c816de5a958c55ebb99bbffe8d0b8fa5d8 Mon Sep 17 00:00:00 2001 From: MariaLukina Date: Thu, 19 Oct 2023 16:17:52 +0700 Subject: [PATCH 05/12] add new script bio_processor_tools --- bio_files_processor.py | 69 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 bio_files_processor.py diff --git a/bio_files_processor.py b/bio_files_processor.py new file mode 100644 index 0000000..044279f --- /dev/null +++ b/bio_files_processor.py @@ -0,0 +1,69 @@ +import os + + +def convert_multiline_fasta_to_oneline(input_fasta, output_fasta = ''): + """ + This function covert multiple string FASTA-file to one-long-string format + :param input_fasta: the pass to the FASTA file + :param output_fasta: name for output FASTA-file, if not defined it will be saved to the directory + 'Result'/input_fasta + Example input: convert_multiline_fasta_to_oneline('example_multiline_fasta.fasta', 'output2'): + """ + if not os.path.isdir('multiple_to_online_results'): + os.mkdir('multiple_to_online_results') + if output_fasta == '': + output_fasta = os.path.join('multiple_to_online_results', os.path.basename(input_fasta)) + else: + output_fasta = os.path.join('multiple_to_online_results', output_fasta + ".fasta") + with open(input_fasta) as input_file, open(output_fasta, 'w') as output_file: + current = [] + output_file.write(input_file.readline()) + while True: + line = input_file.readline() + current.append(line.strip()) + if line.startswith('>'): + output_file.write(''.join(current) + '\n') + output_file.write(line) + current = [] + break + + for line in input_file: + if line.startswith('>'): + output_file.write(''.join(current) + '\n') + output_file.write(line) + current = [] + else: + current.append(line.strip()) + output_file.write(''.join(current) + '\n') + + +def change_fasta_start_pos(input_fasta, n: int, output_fasta=''): + """ + This function moves the position to a new starting nucleotide. + :param input_fasta: data for processing (1-string single fasta) + :param n: position of new start nucleotide (started with 0) + :param output_fasta: name for output fasta file + :return: + """ + if not os.path.isdir('shifted_fasta_results'): + os.mkdir('shifted_fasta_results') + if output_fasta == '': + output_fasta = os.path.join('shifted_fasta_results', os.path.basename(input_fasta)) + else: + output_fasta = os.path.join('shifted_fasta_results', output_fasta + ".fasta") + with open(input_fasta) as input_file: + name = input_file.readline().strip() + string = input_file.readline().strip() + s1 = '' + s2 = '' + if n <= 0: + n = len(string) + n + for i in range(0, len(string)): + if i < n: + s2 = s2 + string[i] + else: + s1 = s1 + string[i] + new_fasta = s1 +s2 + with open(output_fasta, 'w') as output_file: + output_file.write(name +'\n') + output_file.write(new_fasta[0] + '\n') From 539595eeb8daab8d44b46b099a2e0d545c6631f0 Mon Sep 17 00:00:00 2001 From: MariaLukina Date: Thu, 19 Oct 2023 16:20:07 +0700 Subject: [PATCH 06/12] Update fastq_filtration for FASTQ files --- tool_for_bioinformatics.py | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/tool_for_bioinformatics.py b/tool_for_bioinformatics.py index 3e04aca..4d49b00 100644 --- a/tool_for_bioinformatics.py +++ b/tool_for_bioinformatics.py @@ -1,3 +1,5 @@ +from typing import Union +import os import modules.nucleic_acids_functions as na import modules.fastq_filters as ff import modules.amino_acids_functions as aa @@ -7,7 +9,7 @@ 'p', 'T', 'C', 'a'} -def dna_rna_tools(*args: str): +def dna_rna_tools(*args: str) -> str | list: """ Performs functions for working with poly- and oligonucleotide sequences. @@ -60,7 +62,7 @@ def dna_rna_tools(*args: str): return result -def amino_acid_tools(*args: str): +def amino_acid_tools(*args: str) -> list | int | float | str : """ Performs functions for working with protein sequences. @@ -113,17 +115,28 @@ def amino_acid_tools(*args: str): return answer -def fastq_filtration(seqs, gc_bounds=(0, 100), length_bounds=(0, 2 ** 32), quality_treshold=0) -> dict: +def fastq_filtration(input_fastq, gc_bounds=(0, 100), length_bounds=(0, 2 ** 32), quality_treshold=0, output_fastq=''): """ - This function provides you the opportunity to filter the FASTQ list to select sequences - that fit requirements on three parameters: length, GC composition, and quality of the reed + This function provides you the opportunity to filter the FASTQ file to select sequences + that fit requirements on 5 parameters: input and output(optional) files, length, GC composition, + and quality of the reed :parameters + input_fastq: path to fastq file seqs: (dict) dictionary of FASTQ sequences {name: (sequence, quality)} - gc_bounds: (tuple or or float) interval for the of acceptable GC content, in % - length_bounds: (tuple or int) interval for the of acceptable sequence length in number of nucleotide + gc_bounds: (tuple) interval for the of acceptable GC content, in % + length_bounds: (tuple) interval for the of acceptable sequense length in number of nucleotide quality_treshold: (float) threshold value for average quality per nucleotide (phred33 scale) - :return: (dict) new dictionary consists of selected sequences after 3-step filtration + output_fastq = name of output file, ./fastq_filtrator_resuls/output_fastq, if it is not defined, + it will be the same of the input file + """ + if not os.path.isdir('fastq_filtrator_resuls'): + os.mkdir('fastq_filtrator_resuls') + if output_fastq == '': + output_fastq = os.path.join('fastq_filtrator_resuls', os.path.basename(input_fastq)) + else: + output_fastq = os.path.join('fastq_filtrator_resuls', output_fastq + ".fasta") + seqs = convert_fastq_to_dict(input_fastq) if type(gc_bounds) == float or type(gc_bounds) == int: gc_bounds_both_side = (0, gc_bounds) else: @@ -132,6 +145,9 @@ def fastq_filtration(seqs, gc_bounds=(0, 100), length_bounds=(0, 2 ** 32), quali length_bounds_both_side = (0, length_bounds) else: length_bounds_both_side = length_bounds - good_seqs = ff.filter_length(ff.filter_quality(ff.filter_gc(seqs, gc_bounds_both_side), quality_treshold), - length_bounds_both_side) + good_seqs = filter_length(filter_quality(filter_gc(seqs, gc_bounds_both_side), quality_treshold), + length_bounds_both_side) + + write_dict_file_to_fastq(good_seqs, output_fastq) return good_seqs + From 4fab426980a44c9bbf4de5a2fe913f8b576a8f28 Mon Sep 17 00:00:00 2001 From: MariaLukina Date: Thu, 19 Oct 2023 18:59:36 +0700 Subject: [PATCH 07/12] updated_bio_file_processor --- bio_files_processor.py | 1 - modules/fastq_filters.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/bio_files_processor.py b/bio_files_processor.py index 044279f..b65fe39 100644 --- a/bio_files_processor.py +++ b/bio_files_processor.py @@ -43,7 +43,6 @@ def change_fasta_start_pos(input_fasta, n: int, output_fasta=''): :param input_fasta: data for processing (1-string single fasta) :param n: position of new start nucleotide (started with 0) :param output_fasta: name for output fasta file - :return: """ if not os.path.isdir('shifted_fasta_results'): os.mkdir('shifted_fasta_results') diff --git a/modules/fastq_filters.py b/modules/fastq_filters.py index 84226c0..589ca5a 100644 --- a/modules/fastq_filters.py +++ b/modules/fastq_filters.py @@ -60,3 +60,40 @@ def filter_quality(seqs: dict, quality_treshold=0) -> dict: if quality_sum / len(params[1]) >= quality_treshold: d_new[key] = (params[0], params[1]) return d_new + + +def convert_fastq_to_dict(input_path) -> dict: + """ + This function converts fastq file to dictionary with name as a key, and sequence, comment and quality as values + :parameters: + input_path: path for data + :return:(dict) dictionary {name: (sequence, comment, quality}} + """ + with open(input_path) as input_file: + seqs = {} + while True: + key = input_file.readline().strip() + if key == '': + break + seq = input_file.readline().strip() + com = input_file.readline().strip() + qual = input_file.readline().strip() + seqs[key] = (seq, com, qual) + return seqs + + +def write_dict_file_to_fastq(seqs, output_fastq): + """ + This function forms output file from the fastq dictionary {name: (sequence, comment, quality}} + with name as a key, and sequence, comment and quality as values + :parameters: + seqs: dictionary of FASTQ sequences {name: (sequence, quality)} + output_file: filename for output data + :return:(dict) output_file.fastq + """ + with open(output_fastq, 'w') as output_file: + for key, params in seqs.items(): + output_file.write(key + '\n') + output_file.write(params[0] + '\n') + output_file.write(params[1] + '\n') + output_file.write(params[2] + '\n') From 50ee5e3e28eee1666bd94e600a358842de1d2d22 Mon Sep 17 00:00:00 2001 From: MariaLukina Date: Thu, 19 Oct 2023 19:01:29 +0700 Subject: [PATCH 08/12] updated tool_for_bioinformatics --- tool_for_bioinformatics.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tool_for_bioinformatics.py b/tool_for_bioinformatics.py index 4d49b00..cf8e1a5 100644 --- a/tool_for_bioinformatics.py +++ b/tool_for_bioinformatics.py @@ -122,7 +122,6 @@ def fastq_filtration(input_fastq, gc_bounds=(0, 100), length_bounds=(0, 2 ** 32) and quality of the reed :parameters input_fastq: path to fastq file - seqs: (dict) dictionary of FASTQ sequences {name: (sequence, quality)} gc_bounds: (tuple) interval for the of acceptable GC content, in % length_bounds: (tuple) interval for the of acceptable sequense length in number of nucleotide quality_treshold: (float) threshold value for average quality per nucleotide (phred33 scale) From dd27c631d79127553b6c923f428f5e47e681c542 Mon Sep 17 00:00:00 2001 From: MariaLukina Date: Thu, 19 Oct 2023 19:02:35 +0700 Subject: [PATCH 09/12] update README --- README.md | 107 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 3734079..16c6301 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,10 @@ # My junior biochemical tool +This package consists of 2 mini-tools +`tools_for_bioinformatics` designed to work with nucleotide and amino acid sequences and FASTQ files +`bio_files_processor` provides opportunity to manipulate with FASTA files + + +# My junior biochemical tool This package for junior bioinformaticians is designed to work with nucleotide and amino acid sequences and FASTQ files, and consists of three parts. Each module `amino_acid_tools`, `dna_rna_tools` and `fastq_filtration` presents its own possibilities for sequence processing. # `amino_acids_tools` @@ -138,15 +144,16 @@ Output: 'AaGC' This function provides you the opportunity to filter the FASTQ list to select sequences according to requirements on three parameters: length, GC composition, and quality of the reed ### Usage -It is required to input the list of sequences in dictionary format, as well as values for filtering parameters: interval by GC-composition, interval by sequence length, threshold value of average quality of reed -Input example: +It is required to input the list of sequences in dictionary format, as well as values for filtering parameters: interval by GC-composition, interval by sequence length, threshold value of average quality of reed. You also need input file and output file name (optional) + **input_fastq:** FASTQ file +**output_fastq** name of output file, you can find it in fastq_filtrator_resuls directory, if name is not defined, it will be the same of the input file in `fastq_filtration_result` directory + ```Python -fastq_filtration(seqs, gc_bounds=(20, 40), length_bounds=(0, 2 *8), quality_treshold=10) +fastq_filtration('example_fastq.fastq', , gc_bounds=(20, 40), length_bounds=(0, 2 *8), quality_treshold=10, 'outfastq_gc' ) ``` #### Filtering parameters - - seqs: dictionary of FASTQ sequences *{name: (sequence, quality)}* - **gc_bounds:** interval for the of acceptable GC content, in %, *Default value = (0,100)* - **length_bounds**: interval for the of acceptable sequense length in @@ -156,41 +163,99 @@ fastq_filtration(seqs, gc_bounds=(20, 40), length_bounds=(0, 2 *8), quality_tres ### Result: -New dictionary consists of selected sequences after 3-step filtration +New FASTQ file consists of selected sequences after 3-step filtration #### Remarks After running without specifying the filtering parameters, all sequences will be be selected as appropriate You also can specify only the upper limit for GC-content and length filtering ### Examples - ```Python -d = {'a': ('atcaaa', '@@@@@@'), 'b': ('gcc', '@@!'), 'c': ('ga', '!!'), 'd': ('ga', '@@')} +fastq_filtration('example_fastq.fastq', gc_bounds= (80, 100)) ``` +@SRX079804:1:SRR292678:1:1101:1120907:1120907 1:N:0:1 BH:ok +CATGGTGGCG ++SRX079804:1:SRR292678:1:1101:1120907:1120907 1:N:0:1 BH:ok +HHHHHFHHGG +@SRX079804:1:SRR292678:1:1101:1175112:1175112 1:N:0:1 BH:failed +AGGCC ++SRX079804:1:SRR292678:1:1101:1175112:1175112 1:N:0:1 BH:failed +EC8EE +@SRX079804:1:SRR292678:1:1101:1269735:1269735 1:N:0:1 BH:failed +C ++SRX079804:1:SRR292678:1:1101:1269735:1269735 1:N:0:1 BH:failed +G ```Python -fastq_filtration(d) +fastq_filtration('example_fastq.fastq', length_bounds= (8, 12),output_fastq = 'outfastq_length') ``` -Output: {'a': ('atcaaa', '@@@@@@'), 'b': ('gcc', '@@!'), 'c': ('ga', '!!'), 'd': ('ga', '@@')} -No filtration with default values - +@SRX079804:1:SRR292678:1:1101:1119783:1119783 1:N:0:1 BH:failed +TGTTGTGTCAAG ++SRX079804:1:SRR292678:1:1101:1119783:1119783 1:N:0:1 BH:failed +C@ABABEEEEAC +@SRX079804:1:SRR292678:1:1101:1120614:1120614 1:N:0:1 BH:failed +TGCTTTGCTTT ++SRX079804:1:SRR292678:1:1101:1120614:1120614 1:N:0:1 BH:failed +DFDD8FE@FFE +@SRX079804:1:SRR292678:1:1101:1120907:1120907 1:N:0:1 BH:ok +CATGGTGGCG ++SRX079804:1:SRR292678:1:1101:1120907:1120907 1:N:0:1 BH:ok +HHHHHFHHGG +@SRX079804:1:SRR292678:1:1101:1130921:1130921 1:N:0:1 BH:failed +AAGGGTCGA ++SRX079804:1:SRR292678:1:1101:1130921:1130921 1:N:0:1 BH:failed +D@CDDBEEB +@SRX079804:1:SRR292678:1:1101:1156698:1156698 1:N:0:1 BH:failed +GAAAGAAC ++SRX079804:1:SRR292678:1:1101:1156698:1156698 1:N:0:1 BH:failed +E=FFFFFF ```Python -fastq_filtration(d, 40, (0, 3), 10) +fastq_filtration('example_fastq.fastq') ``` -Output: {} - +input file (no filtratation with default parameters) ```Python -fastq_filtration(d, 50, (0, 7), 10) +fastq_filtration('example_fastq.fastq', gc_bounds=(100, 100), length_bounds=(0, 0 ), quality_treshold=0, output_fastq = 'outfastq_none') ``` -Output: {'a': ('atcaaa', '@@@@@@'), 'd': ('ga', '@@')} +empty file + + +# `bio_files_processor` + +works with FASTA files, provides 2 functions + +## `convert_multiline_fasta_to_oneline +This function covert multiple string FASTA-file to one-long-string format + + - **input_fasta**: path to the FASTA file + - **output_fasta**: name for output FASTA-file, if not defined it will be saved to the directory `Result` as `'Result'/input_fasta` +Example input: ```Python -fastq_filtration(d, 50, (0, 7), 0) +convert_multiline_fasta_to_oneline('example_multiline_fasta.fasta', 'output2'): ``` -Output: {'a': ('atcaaa', '@@@@@@'), 'c': ('ga', '!!'), 'd': ('ga', '@@')} +## `change_fasta_start_pos` -##### Contacts -Maria Lukina -maria.v.luk@gmail.com + +This function moves the position to a new starting nucleotide and needs 3 parameters + + - **input_fasta:** data for processing (1-string single fasta) + - **n:** position of new start nucleotide (started with 0) + - **output_fasta:** name for output fasta file + + + +Example input: +```Python +change_fasta_start_pos('example_fasta.fasta', 3, 'output2'): +``` + +Examples: +ACTGGA initial sequence +TGGAAC n =2 +AACTGG n =-1 +AACTGG n = 5 +##### Contacts +Maria Lukina +maria.v.luk@gmail.com \ No newline at end of file From e7b1bf467ef66feb6b9094abdfe3dc7937c69f4a Mon Sep 17 00:00:00 2001 From: MariaLukina Date: Thu, 19 Oct 2023 20:37:49 +0700 Subject: [PATCH 10/12] update tool_for_bioinf: correct import of FASTQ_functions (after dl) --- tool_for_bioinformatics.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tool_for_bioinformatics.py b/tool_for_bioinformatics.py index cf8e1a5..91d9ed3 100644 --- a/tool_for_bioinformatics.py +++ b/tool_for_bioinformatics.py @@ -135,7 +135,7 @@ def fastq_filtration(input_fastq, gc_bounds=(0, 100), length_bounds=(0, 2 ** 32) output_fastq = os.path.join('fastq_filtrator_resuls', os.path.basename(input_fastq)) else: output_fastq = os.path.join('fastq_filtrator_resuls', output_fastq + ".fasta") - seqs = convert_fastq_to_dict(input_fastq) + seqs = ff.convert_fastq_to_dict(input_fastq) if type(gc_bounds) == float or type(gc_bounds) == int: gc_bounds_both_side = (0, gc_bounds) else: @@ -144,9 +144,10 @@ def fastq_filtration(input_fastq, gc_bounds=(0, 100), length_bounds=(0, 2 ** 32) length_bounds_both_side = (0, length_bounds) else: length_bounds_both_side = length_bounds - good_seqs = filter_length(filter_quality(filter_gc(seqs, gc_bounds_both_side), quality_treshold), + good_seqs = ff.filter_length(ff.filter_quality(ff.filter_gc(seqs, gc_bounds_both_side), quality_treshold), length_bounds_both_side) - write_dict_file_to_fastq(good_seqs, output_fastq) + ff.write_dict_file_to_fastq(good_seqs, output_fastq) return good_seqs + From ba201c52108945ccb7b47d4c12f7e00a6c6c1349 Mon Sep 17 00:00:00 2001 From: MariaLukina Date: Fri, 23 Feb 2024 12:42:52 +0700 Subject: [PATCH 11/12] Correct fastq filtration --- .../amino_acids_functions.cpython-312.pyc | Bin 0 -> 5281 bytes .../__pycache__/fastq_filters.cpython-312.pyc | Bin 0 -> 5238 bytes .../nucleic_acids_functions.cpython-312.pyc | Bin 0 -> 2663 bytes modules/fastq_filters.py | 10 +++++----- tool_for_bioinformatics.py | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 modules/__pycache__/amino_acids_functions.cpython-312.pyc create mode 100644 modules/__pycache__/fastq_filters.cpython-312.pyc create mode 100644 modules/__pycache__/nucleic_acids_functions.cpython-312.pyc diff --git a/modules/__pycache__/amino_acids_functions.cpython-312.pyc b/modules/__pycache__/amino_acids_functions.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f201d46639ab3dc72da1de953a7a509f75944cb GIT binary patch literal 5281 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 literal 0 HcmV?d00001 diff --git a/modules/fastq_filters.py b/modules/fastq_filters.py index 589ca5a..8e8924a 100644 --- a/modules/fastq_filters.py +++ b/modules/fastq_filters.py @@ -25,7 +25,7 @@ def filter_gc(seqs: dict, gc_bounds_both_side=(0, 100)) -> dict: d_new = {} for key, params in seqs.items(): if gc_bounds_both_side[1] >= gc_content(params[0]) >= gc_bounds_both_side[0]: - d_new[key] = (params[0], params[1]) + d_new[key] = (params[0], params[1], params[2]) return d_new @@ -40,7 +40,7 @@ def filter_length(seqs: dict, length_bounds_both_side=(0, 2 ** 32)) -> dict: d_new = {} for key, params in seqs.items(): if length_bounds_both_side[1] >= len(params[0]) >= length_bounds_both_side[0]: - d_new[key] = (params[0], params[1]) + d_new[key] = (params[0], params[1], params[2]) return d_new @@ -55,10 +55,10 @@ def filter_quality(seqs: dict, quality_treshold=0) -> dict: d_new = {} for key, params in seqs.items(): quality_sum = 0 - for n in params[1]: + for n in params[2]: quality_sum += ord(n) - 33 - if quality_sum / len(params[1]) >= quality_treshold: - d_new[key] = (params[0], params[1]) + if quality_sum / len(params[2]) >= quality_treshold: + d_new[key] = (params[0], params[1], params[2]) return d_new diff --git a/tool_for_bioinformatics.py b/tool_for_bioinformatics.py index 91d9ed3..150d3a7 100644 --- a/tool_for_bioinformatics.py +++ b/tool_for_bioinformatics.py @@ -150,4 +150,4 @@ def fastq_filtration(input_fastq, gc_bounds=(0, 100), length_bounds=(0, 2 ** 32) ff.write_dict_file_to_fastq(good_seqs, output_fastq) return good_seqs - +fastq_filtration('example_fastq.fastq', gc_bounds=(20, 80), length_bounds=140, quality_treshold=38, output_fastq='') From 2fe1b370b46082bb387a080a9c33f6697c3ae38c Mon Sep 17 00:00:00 2001 From: MariaLukina Date: Fri, 23 Feb 2024 12:50:36 +0700 Subject: [PATCH 12/12] Delete cash --- .../amino_acids_functions.cpython-312.pyc | Bin 5281 -> 0 bytes .../__pycache__/fastq_filters.cpython-312.pyc | Bin 5238 -> 0 bytes .../nucleic_acids_functions.cpython-312.pyc | Bin 2663 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 modules/__pycache__/amino_acids_functions.cpython-312.pyc delete mode 100644 modules/__pycache__/fastq_filters.cpython-312.pyc delete mode 100644 modules/__pycache__/nucleic_acids_functions.cpython-312.pyc diff --git a/modules/__pycache__/amino_acids_functions.cpython-312.pyc b/modules/__pycache__/amino_acids_functions.cpython-312.pyc deleted file mode 100644 index 6f201d46639ab3dc72da1de953a7a509f75944cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5281 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