PyamilySeq 0.5.2__py3-none-any.whl → 0.7.0__py3-none-any.whl

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.
PyamilySeq/utils.py CHANGED
@@ -3,8 +3,33 @@ import shutil
3
3
  import os
4
4
  import glob
5
5
  import collections
6
+ from tempfile import NamedTemporaryFile
7
+ import sys
6
8
 
7
9
 
10
+ ################### We are currently fixed using Table 11
11
+ gencode = {
12
+ 'ATA':'I', 'ATC':'I', 'ATT':'I', 'ATG':'M',
13
+ 'ACA':'T', 'ACC':'T', 'ACG':'T', 'ACT':'T',
14
+ 'AAC':'N', 'AAT':'N', 'AAA':'K', 'AAG':'K',
15
+ 'AGC':'S', 'AGT':'S', 'AGA':'R', 'AGG':'R',
16
+ 'CTA':'L', 'CTC':'L', 'CTG':'L', 'CTT':'L',
17
+ 'CCA':'P', 'CCC':'P', 'CCG':'P', 'CCT':'P',
18
+ 'CAC':'H', 'CAT':'H', 'CAA':'Q', 'CAG':'Q',
19
+ 'CGA':'R', 'CGC':'R', 'CGG':'R', 'CGT':'R',
20
+ 'GTA':'V', 'GTC':'V', 'GTG':'V', 'GTT':'V',
21
+ 'GCA':'A', 'GCC':'A', 'GCG':'A', 'GCT':'A',
22
+ 'GAC':'D', 'GAT':'D', 'GAA':'E', 'GAG':'E',
23
+ 'GGA':'G', 'GGC':'G', 'GGG':'G', 'GGT':'G',
24
+ 'TCA':'S', 'TCC':'S', 'TCG':'S', 'TCT':'S',
25
+ 'TTC':'F', 'TTT':'F', 'TTA':'L', 'TTG':'L',
26
+ 'TAC':'Y', 'TAT':'Y', 'TAA':'*', 'TAG':'*',
27
+ 'TGC':'C', 'TGT':'C', 'TGA':'*', 'TGG':'W'}
28
+
29
+ def translate_frame(sequence):
30
+ translate = ''.join([gencode.get(sequence[3 * i:3 * i + 3], 'X') for i in range(len(sequence) // 3)])
31
+ return translate
32
+
8
33
  def is_tool_installed(tool_name):
9
34
  """Check if a tool is installed and available in PATH."""
10
35
  # Check if the tool is in the system PATH
@@ -30,12 +55,81 @@ def fix_path(path):
30
55
  return fixed_path
31
56
 
32
57
 
58
+ def wrap_sequence(sequence, width=60):
59
+ wrapped_sequence = []
60
+ for i in range(0, len(sequence), width):
61
+ wrapped_sequence.append(sequence[i:i + width])
62
+ return "\n".join(wrapped_sequence)
63
+
64
+
65
+ def read_fasta(fasta_file):
66
+ sequences = {}
67
+ current_sequence = None
68
+ with open(fasta_file, 'r') as file:
69
+ for line in file:
70
+ line = line.strip()
71
+ if not line:
72
+ continue # Skip empty lines
73
+ if line.startswith('>'):
74
+ current_sequence = line[1:] # Remove '>' character
75
+ sequences[current_sequence] = ''
76
+ else:
77
+ sequences[current_sequence] += line
78
+ return sequences
33
79
 
34
80
 
81
+ def reorder_dict_by_keys(original_dict, sorted_keys):
82
+ return {k: original_dict[k] for k in sorted_keys}
83
+ def custom_sort_key(k, dict1, dict2):
84
+ return (len(dict1[k]), len(dict2[k]))
35
85
 
86
+ def sort_keys_by_values(dict1, dict2):
87
+ sorted_keys = sorted(dict1.keys(), key=lambda k: custom_sort_key(k, dict1, dict2), reverse=True)
88
+ return sorted_keys
36
89
 
90
+ def select_longest_gene(sequences):
91
+ """Select the longest sequence for each genome."""
92
+ longest_sequences = {}
93
+ for seq_id, sequence in sequences.items():
94
+ genome = seq_id.split('|')[0] # Assuming genome name can be derived from the sequence ID
95
+ if genome not in longest_sequences or len(sequence) > len(longest_sequences[genome][1]):
96
+ longest_sequences[genome] = (seq_id, sequence)
97
+ return longest_sequences
98
+
99
+
100
+ def run_mafft_on_sequences(options, sequences, output_file):
101
+ #print("Conducting MAFFT alignment.")
102
+ """Run mafft on the given sequences and write to output file."""
103
+ # Create a temporary input file for mafft
104
+ with NamedTemporaryFile('w', delete=False) as temp_input_file:
105
+ for header, sequence in sequences.items():
106
+ temp_input_file.write(f">{header}\n{sequence}\n")
107
+ temp_input_file_path = temp_input_file.name
108
+
109
+ # Run mafft
110
+ try:
111
+ with open(output_file, 'w') as output_f:
112
+ if options.verbose == True:
113
+ subprocess.run(
114
+ ['mafft', '--auto', temp_input_file_path],
115
+ stdout=output_f,
116
+ stderr=sys.stderr,
117
+ check=True
118
+ )
119
+ else:
120
+ subprocess.run(
121
+ ['mafft', '--auto', temp_input_file_path],
122
+ stdout=output_f,
123
+ stderr=subprocess.DEVNULL, # Suppress stderr
124
+ check=True
125
+ )
126
+ finally:
127
+ os.remove(temp_input_file_path) # Clean up the temporary file
37
128
 
38
- def read_separate_files(input_dir, name_split, combined_out):
129
+
130
+
131
+
132
+ def read_separate_files(input_dir, name_split, gene_ident, combined_out, translate):
39
133
  with open(combined_out, 'w') as combined_out_file:
40
134
  for gff_file in glob.glob(os.path.join(input_dir, '*' + name_split)):
41
135
  genome_name = os.path.basename(gff_file).split(name_split)[0]
@@ -45,15 +139,21 @@ def read_separate_files(input_dir, name_split, combined_out):
45
139
 
46
140
  gff_features = []
47
141
  with open(gff_file, 'r') as file:
142
+ seen_seq_ids = collections.defaultdict(int)
48
143
  lines = file.readlines()
49
144
  for line in lines:
50
145
  line_data = line.split('\t')
51
146
  if len(line_data) == 9:
52
- if line_data[2] == 'CDS':
147
+ if any(gene_type in line_data[2] for gene_type in gene_ident):
53
148
  contig = line_data[0]
54
149
  feature = line_data[2]
55
150
  strand = line_data[6]
56
151
  start, end = int(line_data[3]), int(line_data[4])
152
+ if seq_id in seen_seq_ids:
153
+ seq_id += '_' + str(seen_seq_ids[seq_id])
154
+ seen_seq_ids[seq_id] + 1
155
+ else:
156
+ seen_seq_ids[seq_id] = 1
57
157
  seq_id = line_data[8].split('ID=')[1].split(';')[0]
58
158
  gff_features.append((contig, start, end, strand, feature, seq_id))
59
159
  fasta_dict = collections.defaultdict(str)
@@ -81,18 +181,20 @@ def read_separate_files(input_dir, name_split, combined_out):
81
181
  corrected_stop = max(len(fasta_dict[contig][0]) - int(start - 1), 1)
82
182
  full_sequence = fasta_dict[contig][1]
83
183
  cds_sequence = full_sequence[corrected_start:corrected_stop]
84
-
184
+ if translate == True:
185
+ cds_sequence = translate_frame(cds_sequence)
85
186
  wrapped_sequence = '\n'.join([cds_sequence[i:i + 60] for i in range(0, len(cds_sequence), 60)])
86
187
  combined_out_file.write(f">{genome_name}|{seq_id}\n{wrapped_sequence}\n")
87
188
 
88
189
 
89
- def read_combined_files(input_dir, name_split, combined_out):
190
+ def read_combined_files(input_dir, name_split, gene_ident, combined_out, translate):
90
191
  with open(combined_out, 'w') as combined_out_file:
91
192
  for gff_file in glob.glob(os.path.join(input_dir, '*' + name_split)):
92
193
  genome_name = os.path.basename(gff_file).split(name_split)[0]
93
194
  fasta_dict = collections.defaultdict(str)
94
195
  gff_features = []
95
196
  with open(gff_file, 'r') as file:
197
+ seen_seq_ids = collections.defaultdict(int)
96
198
  lines = file.readlines()
97
199
  fasta_section = False
98
200
  for line in lines:
@@ -108,12 +210,17 @@ def read_combined_files(input_dir, name_split, combined_out):
108
210
  else:
109
211
  line_data = line.split('\t')
110
212
  if len(line_data) == 9:
111
- if line_data[2] == 'CDS':
213
+ if any(gene_type in line_data[2] for gene_type in gene_ident):
112
214
  contig = line_data[0]
113
215
  feature = line_data[2]
114
216
  strand = line_data[6]
115
217
  start, end = int(line_data[3]), int(line_data[4])
116
218
  seq_id = line_data[8].split('ID=')[1].split(';')[0]
219
+ if seq_id in seen_seq_ids:
220
+ seq_id += '_' + str(seen_seq_ids[seq_id])
221
+ seen_seq_ids[seq_id] + 1
222
+ else:
223
+ seen_seq_ids[seq_id] = 1
117
224
  gff_features.append((contig, start, end, strand, feature, seq_id))
118
225
 
119
226
  for contig, fasta in fasta_dict.items():
@@ -132,5 +239,91 @@ def read_combined_files(input_dir, name_split, combined_out):
132
239
  full_sequence = fasta_dict[contig][1]
133
240
  cds_sequence = full_sequence[corrected_start:corrected_stop]
134
241
 
242
+ if translate == True:
243
+ cds_sequence = translate_frame(cds_sequence)
135
244
  wrapped_sequence = '\n'.join([cds_sequence[i:i + 60] for i in range(0, len(cds_sequence), 60)])
136
- combined_out_file.write(f">{genome_name}|{seq_id}\n{wrapped_sequence}\n")
245
+ combined_out_file.write(f">{genome_name}|{seq_id}\n{wrapped_sequence}\n")
246
+
247
+
248
+ def read_fasta_files(input_dir, name_split, combined_out, translate):
249
+ with open(combined_out, 'w') as combined_out_file:
250
+ for fasta_file in glob.glob(os.path.join(input_dir, '*' + name_split)):
251
+ genome_name = os.path.basename(fasta_file).split(name_split)[0]
252
+ fasta_dict = collections.defaultdict(str)
253
+ with open(fasta_file, 'r') as file:
254
+ lines = file.readlines()
255
+ for line in lines:
256
+ if line.startswith('>'):
257
+ current_seq = line[1:].split()[0]
258
+ fasta_dict[current_seq] = ''
259
+ else:
260
+ fasta_dict[current_seq] +=line.strip()
261
+ for id, seq in fasta_dict.items():
262
+ if translate == True:
263
+ seq = translate_frame(seq)
264
+ wrapped_sequence = '\n'.join([seq[i:i + 60] for i in range(0, len(seq), 60)])
265
+ combined_out_file.write(f">{genome_name}|{id}\n{wrapped_sequence}\n")
266
+
267
+
268
+ def write_groups(options,output_dir, key_order, cores, sequences, pangenome_clusters_First_sequences_sorted, combined_pangenome_clusters_Second_sequences):
269
+ # Create output directory if it doesn't exist
270
+ if not os.path.exists(output_dir):
271
+ os.makedirs(output_dir)
272
+ for key_prefix in key_order:
273
+ for key, values in cores.items():
274
+ if any(part in options.write_groups.split(',') for part in key.split('_')):
275
+ if key.startswith(key_prefix):
276
+ for value in values:
277
+ output_filename = f"{key}_{value}.fasta"
278
+ if 'First' in key_prefix:
279
+ sequences_to_write = pangenome_clusters_First_sequences_sorted[value]
280
+ else: # combined_pangenome_clusters_Second_sequences is None if reclustered isn't being used
281
+ sequences_to_write = combined_pangenome_clusters_Second_sequences[value]
282
+ # Write sequences to output file that are in the sequences dictionary
283
+ with open(os.path.join(output_dir, output_filename), 'w') as outfile:
284
+ for header in sequences_to_write:
285
+ if header in sequences:
286
+ outfile.write(f">{header}\n")
287
+ wrapped_sequence = wrap_sequence(sequences[header])
288
+ outfile.write(f"{wrapped_sequence}\n")
289
+ else:
290
+ if options.verbose == True:
291
+ print("Sequence " + header + " Not found in original_fasta file.")
292
+
293
+ def process_gene_families(options, directory, output_file):
294
+ """Process each gene family file to select the longest sequence per genome and concatenate aligned sequences."""
295
+ concatenated_sequences = {}
296
+ output_file = directory.replace('Gene_Families_Output',output_file)
297
+
298
+ # Iterate over each gene family file
299
+ for gene_file in os.listdir(directory):
300
+ if gene_file.endswith('.fasta'):
301
+ gene_path = os.path.join(directory, gene_file)
302
+
303
+ # Read sequences from the gene family file
304
+ sequences = read_fasta(gene_path)
305
+
306
+ # Select the longest sequence for each genome
307
+ longest_sequences = select_longest_gene(sequences)
308
+
309
+ # Run mafft on the longest sequences
310
+ aligned_file = f"{gene_file}_aligned.fasta"
311
+ run_mafft_on_sequences(options, {seq_id: seq for seq_id, seq in longest_sequences.values()}, aligned_file)
312
+
313
+ # Read aligned sequences and concatenate them
314
+ aligned_sequences = read_fasta(aligned_file)
315
+ for genome, aligned_seq in aligned_sequences.items():
316
+ genome_name = genome.split('|')[0]
317
+ if genome_name not in concatenated_sequences:
318
+ concatenated_sequences[genome_name] = ""
319
+ concatenated_sequences[genome_name] += aligned_seq
320
+
321
+ # Clean up aligned file
322
+ os.remove(aligned_file)
323
+
324
+ # Write the concatenated sequences to the output file
325
+ with open(output_file, 'w') as out:
326
+ for genome, sequence in concatenated_sequences.items():
327
+ out.write(f">{genome}\n")
328
+ wrapped_sequence = wrap_sequence(sequence, 60)
329
+ out.write(f"{wrapped_sequence}\n")
@@ -0,0 +1,251 @@
1
+ Metadata-Version: 2.1
2
+ Name: PyamilySeq
3
+ Version: 0.7.0
4
+ Summary: PyamilySeq - A a tool to look for sequence-based gene groups identified by clustering methods such as CD-HIT, DIAMOND, BLAST or MMseqs2.
5
+ Home-page: https://github.com/NickJD/PyamilySeq
6
+ Author: Nicholas Dimonaco
7
+ Author-email: nicholas@dimonaco.co.uk
8
+ Project-URL: Bug Tracker, https://github.com/NickJD/PyamilySeq/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.6
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+
16
+ # PyamilySeq - !BETA!
17
+ **PyamilySeq** is a Python tool for clustering gene sequences into groups based on sequence similarity identified by tools such as CD-HIT, BLAST, DIAMOND or MMseqs2.
18
+ This work is an extension of the gene family / pangenome tool developed for the StORF-Reporter publication in NAR (https://doi.org/10.1093/nar/gkad814).
19
+
20
+ ## Features
21
+ - **End-to-End**: PyamilySeq can take a directory of GFF+FASTA files, run CD-HIT for clustering and process the results.
22
+ - **Clustering input**: Supports input from CD-HIT formatted files as well as CSV and TSV edge lists (MMseqs2 and -outfmt 6 from BLAST/DIAMOND).
23
+ - **Reclustering**: Allows for the addition of new sequences post-initial clustering - Ensures continuity of contemporary clustering results and highlights impact of novel gene predictions.
24
+ - **'Genus Mode'**: Unlike other 'pangenome' tools, PyamilySeq can identify gene groups found across multiple genera as unique entities (see below).
25
+ - **Output**: Generates a 'Roary/Panaroo' formatted presence-absence CSV formatted file for downstream analysis.
26
+ - User-define species-/genus-wide gene groups - User has control over grouping parameters (core = 99/95% or min 6 genera etc).
27
+ - Aligns representative sequences using MAFFT.
28
+ - Output concatenated aligned sequences for tree building.
29
+ - Optionally output sequences of each separate identified gene group.
30
+
31
+ ## Installation
32
+ PyamilySeq probably requires Python 3.6 or higher. Install using pip:
33
+
34
+ ```bash
35
+ pip install PyamilySeq
36
+ ```
37
+
38
+ ## Example usage: Below are two examples of running PyamilySeq in its two main modes.
39
+ ### 'Full Mode': Will conduct clustering of sequences with CD-HIT as part of PyamilySeq run
40
+ ```
41
+ PyamilySeq -run_mode Full -group_mode Species -clustering_format CD-HIT -output_dir .../test_data/testing/Full
42
+ -input_type combined -input_dir .../test_data/genomes -name_split _combined.gff3 -pid 0.95 -len_diff 0.80
43
+ -gpa -a -w 99
44
+ ```
45
+ ### 'Partial Mode': Will take the output of a sequence clustering.
46
+ ```
47
+ PyamilySeq -run_mode Partial -group_mode Species -clustering_format TSV -output_dir .../test_data/Species/testing/Partial
48
+ -cluster_file .../test_data/Species/MMseqs2/combined_Ensmbl_pep_cluster.tsv
49
+ -original_fasta .../test_data/species/combined_Ensmbl_cds.fasta -gpa -a -w 99 -verbose
50
+
51
+ ```
52
+ #### Note: '-clustering_format TSV/CSV' requires input to be two in two columns as below (Same format as MMseqs2 tsv) - Genome name and sequence name are separated by '|'.
53
+ ```
54
+ Escherichia_coli_110957|ENSB:lL-zIKt-gh0oSno Escherichia_coli_110957|ENSB:lL-zIKt-gh0oSno
55
+ Escherichia_coli_110957|ENSB:lL-zIKt-gh0oSno Escherichia_coli_113290|ENSB:2fj4rJ8e8Z9PNdX
56
+ Escherichia_coli_110957|ENSB:lL-zIKt-gh0oSno Escherichia_coli_b185|ENSB:G_PVe28-ej8q-3S
57
+ Escherichia_coli_110957|ENSB:TIZS9kbTvShDvyX Escherichia_coli_110957|ENSB:TIZS9kbTvShDvyX
58
+ ```
59
+ ### Example output:
60
+ ```
61
+ Running PyamilySeq v0.7.0
62
+ Calculating Groups
63
+ Gene Groups:
64
+ First_core_99: 2682
65
+ First_core_95: 0
66
+ First_core_15: 3789
67
+ First_core_0: 6469
68
+ Total Number of First Gene Groups (Including Singletons): 12940
69
+ Outputting gene_presence_absence file
70
+ Outputting gene group FASTA files
71
+ Processing gene group alignment
72
+ Thank you for using PyamilySeq -- A detailed user manual can be found at https://github.com/NickJD/PyamilySeq
73
+ Please report any issues to: https://github.com/NickJD/PyamilySeq/issues
74
+ ```
75
+ ## Genus mode:
76
+ ### In addition to "Species mode" (see above) which reports gene groups the same as pangenome tools such as Roary and Panaroo, Genus mode reports gene groups identified across multiple genera.
77
+ #### Example:
78
+ ```
79
+ PyamilySeq -run_mode Partial -group_mode Genus -clustering_format CD-HIT -output_dir .../test_data/genus/testing/
80
+ -cluster_file .../test_data/genus/CD-HIT/combined_cds_cd-hit_80_60.clstr -gpa
81
+ ```
82
+ ```commandline
83
+ Running PyamilySeq v0.7.0
84
+ Calculating Groups
85
+ Genus Groups:
86
+ First_genera_1: 28549
87
+ First_genera_2: 12
88
+ First_genera_3: 0
89
+ First_genera_>: 0
90
+ Total Number of First Gene Groups (Including Singletons): 28561
91
+ Outputting gene_presence_absence file
92
+ Thank you for using PyamilySeq -- A detailed user manual can be found at https://github.com/NickJD/PyamilySeq
93
+ Please report any issues to: https://github.com/NickJD/PyamilySeq/issues
94
+ #####
95
+ ```
96
+
97
+ ## Reclustering:
98
+ ### Reclustering can be used to see where additional sequences/genes lay in relation to a contemporary pangenome/gene grouping.
99
+ ```
100
+ PyamilySeq -run_mode Partial -group_mode Species -clustering_format CD-HIT -output_dir .../test_data/species/CD-HIT/testing
101
+ -cluster_file .../test_data/species/CD-HIT/E-coli_extracted_cds_cd-hit_90_60.clstr -gpa
102
+ -reclustered .../test_data/species/CD-HIT/E-coli_extracted_cds_cd-hit_90_60_And_StORFs_cds_90_60.clstr
103
+ ```
104
+ #### As can be seen below, the additional sequences recovered by the StORF-Reporter annotation tool have 'extended' contemporary or created entirely new gene groups. 'First' corresponds to the groups identified from the first clustering round and 'Second' for the second. In 'reclustering' mode, First_core_# groups are unaffected thus retaining the initial grouping information.
105
+ ```commandline
106
+ Running PyamilySeq v0.7.0
107
+ Calculating Groups
108
+ Gene Groups:
109
+ First_core_99: 69
110
+ First_core_95: 1002
111
+ First_core_15: 4716
112
+ First_core_0: 37960
113
+ extended_core_99: 6
114
+ extended_core_95: 73
115
+ extended_core_15: 331
116
+ extended_core_0: 582
117
+ combined_core_99: 4
118
+ combined_core_95: 88
119
+ combined_core_15: 455
120
+ combined_core_0: 228
121
+ Second_core_99: 0
122
+ Second_core_95: 5
123
+ Second_core_15: 254
124
+ Second_core_0: 3714
125
+ only_Second_core_99: 6
126
+ only_Second_core_95: 364
127
+ only_Second_core_15: 3950
128
+ only_Second_core_0: 31269
129
+ Total Number of First Gene Groups (Including Singletons): 43747
130
+ Total Number of Second Gene Groups (Including Singletons): 66525
131
+ Total Number of First Gene Groups That Had Additional Second Sequences But Not New Genomes: 9593
132
+ Outputting gene_presence_absence file
133
+ Thank you for using PyamilySeq -- A detailed user manual can be found at https://github.com/NickJD/PyamilySeq
134
+ Please report any issues to: https://github.com/NickJD/PyamilySeq/issues
135
+ #####
136
+ ```
137
+
138
+ ## PyamilySeq - Menu:
139
+ ### PyamilySeq is separated into two main 'run modes', Full and Partial. They each have their own set of required and optional arguments.
140
+ ```
141
+ Running PyamilySeq v0.7.0
142
+ usage: PyamilySeq.py [-h] -run_mode {Full,Partial} -group_mode {Species,Genus} -clustering_format {CD-HIT,TSV,CSV} -output_dir OUTPUT_DIR
143
+ [-input_type {separate,combined}] [-input_dir INPUT_DIR] [-name_split NAME_SPLIT] [-sequence_type {AA,DNA}] [-gene_ident GENE_IDENT]
144
+ [-pid PIDENT] [-len_diff LEN_DIFF] [-mem CLUSTERING_MEMORY] [-t CLUSTERING_THREADS] [-cluster_file CLUSTER_FILE]
145
+ [-reclustered RECLUSTERED] [-seq_tag SEQUENCE_TAG] [-core_groups CORE_GROUPS] [-genus_groups GENUS_GROUPS] [-w WRITE_GROUPS] [-a]
146
+ [-original_fasta ORIGINAL_FASTA] [-gpa] [-verbose] [-v]
147
+
148
+ PyamilySeq v0.7.0: A tool that groups genes into unique clusters.
149
+
150
+ options:
151
+ -h, --help show this help message and exit
152
+
153
+ Required Arguments:
154
+ -run_mode {Full,Partial}
155
+ Run Mode: Should PyamilySeq be run in "Full" or "Partial" mode?
156
+ -group_mode {Species,Genus}
157
+ Group Mode: Should PyamilySeq be run in "Species" or "Genus" mode?
158
+ -clustering_format {CD-HIT,TSV,CSV}
159
+ Clustering format to use: CD-HIT or TSV (MMseqs2, BLAST, DIAMOND) / CSV edge-list file (Node1 Node2).
160
+ -output_dir OUTPUT_DIR
161
+ Directory for all output files.
162
+
163
+ Full-Mode Arguments - Required when "-run_mode Full" is used:
164
+ -input_type {separate,combined}
165
+ Type of input files: 'separate' for separate FASTA and GFF files, 'combined' for GFF files with embedded FASTA sequences.
166
+ -input_dir INPUT_DIR Directory containing GFF/FASTA files.
167
+ -name_split NAME_SPLIT
168
+ substring used to split the filename and extract the genome name ('_combined.gff3' or '.gff').
169
+ -sequence_type {AA,DNA}
170
+ Default - DNA: Should clustering be performed in "DNA" or "AA" mode?
171
+ -gene_ident GENE_IDENT
172
+ Identifier used for extraction of sequences such as
173
+ "misc_RNA,gene,mRNA,CDS,rRNA,tRNA,tmRNA,CRISPR,ncRNA,regulatory_region,oriC,pseudo"
174
+ -pid PIDENT Default 0.95: Pident threshold for clustering.
175
+ -len_diff LEN_DIFF Default 0.80: Minimum length difference between clustered sequences - (-s) threshold for CD-HIT clustering.
176
+
177
+ Clustering Runtime Arguments - Optional when "-run_mode Full" is used:
178
+ -mem CLUSTERING_MEMORY
179
+ Default 4000: Memory to be allocated for clustering (in MBs).
180
+ -t CLUSTERING_THREADS
181
+ Default 4: Threads to be allocated for clustering.
182
+
183
+ Partial-Mode Arguments - Required when "-run_mode Partial" is used:
184
+ -cluster_file CLUSTER_FILE
185
+ Clustering output file containing CD-HIT, TSV or CSV Edge List
186
+
187
+ Grouping Arguments - Use to fine-tune grouping of genes after clustering:
188
+ -reclustered RECLUSTERED
189
+ Currently only works on Partial Mode: Clustering output file from secondary round of clustering.
190
+ -seq_tag SEQUENCE_TAG
191
+ Default - "StORF": Unique identifier to be used to distinguish the second of two rounds of clustered sequences
192
+ -core_groups CORE_GROUPS
193
+ Default - ('99,95,15'): Gene family groups to use for "Species" mode
194
+ -genus_groups GENUS_GROUPS
195
+ Default - ('1,2,3,4,5,6'): Gene family groups to use for "Genus" mode
196
+
197
+ Output Parameters:
198
+ -w WRITE_GROUPS Default - No output: Output sequences of identified groups (provide levels at which to output - Species "-w 99,95" Genus "-w 2,3" -
199
+ Must provide FASTA file with -original_fasta if in Partial run mode.
200
+ -a Default - No output: SLOW! (Only works for Species mode) Output aligned and concatinated sequences of identified groups -provide
201
+ group levels at which to output "-w 99,95" - Must provide FASTA file with -original_fasta in Partialrun mode.
202
+ -original_fasta ORIGINAL_FASTA
203
+ FASTA file to use in conjunction with "-w" or "-con" when running in Partial Mode.
204
+ -gpa Default - False: If selected, a Roary/Panaroo formatted gene_presence_absence.csv will be created - Required for Coinfinder and
205
+ other downstream tools
206
+
207
+ Misc:
208
+ -verbose Default - False: Print out runtime messages
209
+ -v Default - False: Print out version number and exit
210
+ ```
211
+
212
+
213
+
214
+
215
+
216
+ ## Seq-Combiner: This tool is provided to enable the pre-processing of multiple GFF/FASTA files together ready to be clustered by the user.
217
+ ### Example:
218
+ ```bash
219
+ Seq-Combiner -input_dir .../test_data/genomes -name_split _combined.gff3 -output_dir.../test_data -output_name combine_fasta_seqs.fa -input_type combined
220
+ ```
221
+ ### Seq-Combiner Menu:
222
+ ```
223
+ usage: Seq_Combiner.py [-h] -input_dir INPUT_DIR -input_type {separate,combined,fasta} -name_split NAME_SPLIT -output_dir OUTPUT_DIR -output_name OUTPUT_FILE [-gene_ident GENE_IDENT] [-translate] [-v]
224
+
225
+ Seq-Combiner v0.7.0: A tool to extract sequences from GFF/FASTA files.
226
+
227
+ options:
228
+ -h, --help show this help message and exit
229
+
230
+ Required Arguments:
231
+ -input_dir INPUT_DIR Directory location where the files are located.
232
+ -input_type {separate,combined,fasta}
233
+ Type of input files: "separate" for separate FASTA and GFF files, "combined" for GFF files with embedded FASTA sequences and "fasta" for combining multiple FASTA files together.
234
+ -name_split NAME_SPLIT
235
+ substring used to split the filename and extract the genome name ('_combined.gff3' or '.gff').
236
+ -output_dir OUTPUT_DIR
237
+ Directory for all output files.
238
+ -output_name OUTPUT_FILE
239
+ Output file name.
240
+
241
+ Optional Arguments:
242
+ -gene_ident GENE_IDENT
243
+ Default - "CDS": Identifier used for extraction of sequences such as "misc_RNA,gene,mRNA,CDS,rRNA,tRNA,tmRNA,CRISPR,ncRNA,regulatory_region,oriC,pseudo" - Not compatible with "fasta" input mode.
244
+ -translate Default - False: Translate extracted sequences to their AA counterpart?
245
+
246
+ Misc Arguments:
247
+ -v Print out version number and exit
248
+
249
+
250
+ ```
251
+ ### All example input and output data can be found in the 'test_data' directory.
@@ -0,0 +1,14 @@
1
+ PyamilySeq/Constants.py,sha256=RSX5-UuBXOrbEv3ETN415RwqoB6WmNe5eD-p7L15CJA,31
2
+ PyamilySeq/PyamilySeq.py,sha256=wmdOVxxRKqsamsEWgnVVCYETUaYOEQQVYERpClrg4Zw,15203
3
+ PyamilySeq/PyamilySeq_Genus.py,sha256=ZjD61mTW7NgmsfGfFVEXeIZoSCha9PaLtMPnqdTtacU,12413
4
+ PyamilySeq/PyamilySeq_Species.py,sha256=WL6pu8hlGpnemcpu1tLFmlUlPd4vJpQSW4Om5Hclu_k,14438
5
+ PyamilySeq/Seq_Combiner.py,sha256=dPDu6LlT3B-ZDn3wKZ3AeWraDgv2Tub_16l9CLc3tQ0,3353
6
+ PyamilySeq/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ PyamilySeq/clusterings.py,sha256=rcWFv0IiWoS4aUNRjDDwNEL86l1wIKa4vK4htAxy8Hg,18787
8
+ PyamilySeq/utils.py,sha256=-0OZxmX96kOTzms8gnbFBvc5DL6NsqNHNpLpQ4UjNk8,15726
9
+ PyamilySeq-0.7.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
10
+ PyamilySeq-0.7.0.dist-info/METADATA,sha256=JDhA1JdFaESNwtqzWjRgaA92lrmVFNJWQZUonHgJuvA,13105
11
+ PyamilySeq-0.7.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
12
+ PyamilySeq-0.7.0.dist-info/entry_points.txt,sha256=QtXD1tmnLvRAkIpGWZgXm1lfLH8GGeCwxmgoHZaTp98,102
13
+ PyamilySeq-0.7.0.dist-info/top_level.txt,sha256=J6JhugUQTq4rq96yibAlQu3o4KCM9WuYfqr3w1r119M,11
14
+ PyamilySeq-0.7.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (71.1.0)
2
+ Generator: setuptools (72.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5