Add Vercel configuration for rewrites and build settings

This commit is contained in:
2025-12-17 17:47:45 +08:00
parent 072524e303
commit 0d31d42de4
32 changed files with 7435 additions and 289 deletions
+316
View File
@@ -0,0 +1,316 @@
#! /usr/bin/env python3
import os
import re
import argparse
import sys
from Bio import SeqIO
from Bio.SeqRecord import SeqRecord
from Bio.Seq import Seq
from pathlib import Path
import logging
logging.basicConfig(level=logging.DEBUG, format="[%(levelname)s]: %(message)s")
class BestHit:
def __init__(self, e_value: float | None = None, target_name: str | None = None):
self.e_value = e_value
self.target_name = target_name
def parse_fasta(fasta_file_path) -> dict[str, str]:
"""
Parse a FASTA file and return a list of sequence ids.
Args:
fasta_file_path: Path to the FASTA file
Returns:
list: Dictionary of sequences
"""
sequences: dict[str, str] = {}
try:
for record in SeqIO.parse(fasta_file_path, "fasta"):
sequences[record.id] = str(record.seq)
except Exception as e:
logging.error(f"Error parsing FASTA file {fasta_file_path}: {e}")
return sequences
def get_ids_from_fasta(fasta_file_path) -> list[str]:
"""
Parse a FASTA file and return a list of sequence ids.
Args:
fasta_file_path: Path to the FASTA file
Returns:
list: List of sequence ids
"""
seqs = parse_fasta(fasta_file_path)
return list(seqs.keys())
def parse_hmmer_tbl(tbl_file_path) -> BestHit:
"""
Parse HMMER tbl format result file and extract best hit information
Args:
tbl_file_path: Path to the tbl file
Returns:
dict: Best hit information
"""
best_hit = BestHit()
try:
with open(tbl_file_path, "r") as f:
for line in f:
# Skip comment lines
if line.startswith("#"):
continue
# Split line (tbl format is typically space or tab separated)
parts = re.split(r"\s+", line.strip())
if len(parts) < 5:
continue
# Extract key information: target name, E-value, score, etc.
# tbl format columns: target name, target accession, query name, query accession, E-value, score, etc.
target_name = parts[0]
e_value = float(parts[4]) # Full sequence E-value
# If it's a new sequence or we found a better hit (lower E-value)
if best_hit.e_value is None or e_value < best_hit.e_value:
best_hit = BestHit(e_value=e_value, target_name=target_name)
except Exception as e:
logging.error(f"Error parsing tbl file {tbl_file_path}: {e}")
return BestHit()
return best_hit
def find_corresponding_files(fasta_dir, tbl_dir) -> list[tuple[Path, Path]]:
"""
Find corresponding FASTA and tbl file pairs
Args:
fasta_dir: Directory containing FASTA files
tbl_dir: Directory containing tbl result files
Returns:
list: List of (fasta_file_path, tbl_file_path) tuples
"""
file_pairs: list[tuple[Path, Path]] = []
# Get all FASTA files
fasta_files = {}
for fasta_path in Path(fasta_dir).glob("*.fa"):
stem = fasta_path.stem
fasta_files[stem] = fasta_path
# Find corresponding tbl files
for stem, fasta_path in fasta_files.items():
tbl_name = f"{stem}.fa.hmmsearch.tblout"
tbl_path = Path(tbl_dir) / tbl_name
if tbl_path.exists():
file_pairs.append((fasta_path, tbl_path))
else:
logging.warning(f"No corresponding tbl file found for {stem}")
return file_pairs
def add_best_hit_to_ogs_dir(
file_pair: tuple[Path, Path],
all_sequences: dict[str, str],
ogs_dir: Path,
species_name: str | None = None,
) -> tuple[str, list[str]]:
"""
Add best hit information to FASTA file
Args:
file_pair: Tuple of (fasta_path, tbl_path)
all_sequences: Dictionary of homolog sequences
ogs_dir: Directory to save FASTA files
species_name: Species name of candidate species
Returns:
tuple: (stem, seq_ids)
"""
fasta_path, tbl_path = file_pair
# Parse tbl file to get best hits
best_hit = parse_hmmer_tbl(tbl_path)
if not best_hit.target_name:
logging.warning(f"No valid hits found in {tbl_path}, skipping...")
return fasta_path.stem, []
best_seq = best_hit.target_name
seq_ids = get_ids_from_fasta(fasta_path)
seqs: dict[str, str] = {}
for seq_id in seq_ids:
seq = all_sequences.get(seq_id)
if not seq:
logging.warning(f"Sequence ID {seq_id} not found! Skipping...")
return fasta_path.stem, []
seqs[seq_id] = seq
modified_ogs_seq_record = [
SeqRecord(seq=Seq(v), id=k.split("@")[0], description="")
for k, v in seqs.items()
]
homolog_dir = Path(ogs_dir) / fasta_path.stem
homolog_dir.mkdir(parents=True, exist_ok=True)
modified_ogs_seq_path = homolog_dir / f"{fasta_path.stem}.fa"
SeqIO.write(modified_ogs_seq_record, modified_ogs_seq_path, "fasta")
homolog_seq = all_sequences.get(best_seq)
if not homolog_seq:
logging.warning(f"Best hit sequence {best_seq} not found! Skipping...")
return fasta_path.stem, []
if not species_name:
species_name = best_seq.split("@")[0]
homolog_seq_path = homolog_dir / f"{fasta_path.stem}_{species_name}.fa"
homolog_seq_record = SeqRecord(
seq=Seq(homolog_seq), id=best_seq.split("@")[0], description=""
)
SeqIO.write([homolog_seq_record], homolog_seq_path, "fasta")
seq_ids.append(best_seq)
return fasta_path.stem, seq_ids
def process_all_files(fasta_dir, tbl_dir, output_dir, all_fasta, species_name):
"""
Process all FASTA and tbl file pairs
Args:
fasta_dir: Directory containing FASTA files
tbl_dir: Directory containing tbl result files
output_file: Output file path
all_fasta: FASTA format cds file of candidate species
"""
logging.info("Starting file processing...")
logging.info(f"FASTA directory: {fasta_dir}")
logging.info(f"tbl directory: {tbl_dir}")
logging.info(f"Output Directory: {output_dir}")
logging.info(f"Homolog FASTA file: {all_fasta}")
og_list = {}
all_sequences = parse_fasta(all_fasta)
if not all_sequences:
logging.error(f"No sequences found in FASTA file {all_fasta}")
sys.exit(1)
# Find corresponding file pairs
file_pairs = find_corresponding_files(fasta_dir, tbl_dir)
if not file_pairs:
logging.error("No corresponding FASTA-tbl file pairs found")
sys.exit(1)
logging.info(f"Found {len(file_pairs)} file pairs to process")
output_file = Path(output_dir) / "updated_ogs_list.txt"
ogs_dir = Path(output_dir) / "ogs"
ogs_dir.mkdir(parents=True, exist_ok=True)
# Process each file pair
for i, file_pair in enumerate(file_pairs, 1):
logging.info(f"Processing pair {i}/{len(file_pairs)}:")
stem, seq_ids = add_best_hit_to_ogs_dir(
file_pair, all_sequences, ogs_dir, species_name
)
if not seq_ids:
logging.info(f"Skipping {stem}!")
continue
og_list[stem] = seq_ids
with open(output_file, "w") as out_f:
for og, ids in og_list.items():
out_f.write(f"{og}\t" + "\t".join(ids) + "\n")
logging.info(f"\nProcessing completed! All results saved to: {output_dir}")
logging.info(f"Updated OGS list saved to: {output_file}")
logging.info(f"Total OGS processed successfully: {len(og_list)}")
def main(fasta_directory, tbl_directory, output_directory, all_fasta, species_name):
"""
Main function - take paths and run processing
Args:
fasta_directory: Folder containing FASTA files
tbl_directory: Folder containing tbl result files
output_file: Output file path
all_fasta: FASTA format cds file of candidate species
species_name: Species name of candidate species
"""
# Check if input directories exist
if not os.path.exists(fasta_directory):
logging.error(f"FASTA directory does not exist {fasta_directory}")
sys.exit(1)
if not os.path.exists(tbl_directory):
logging.error(f"tbl directory does not exist {tbl_directory}")
sys.exit(1)
try:
Path(output_directory).mkdir(parents=True, exist_ok=True)
except Exception as e:
logging.error(f"Error creating output directory {output_directory}: {e}")
sys.exit(1)
if not os.path.exists(all_fasta):
logging.error(f"Homolog FASTA file does not exist {all_fasta}")
sys.exit(1)
# Process all files
process_all_files(
fasta_directory, tbl_directory, output_directory, all_fasta, species_name
)
if __name__ == "__main__":
# Parse command-line arguments and call main
parser = argparse.ArgumentParser(
description="Add HMMER best hit into orthologs FASTA."
)
parser.add_argument(
"-d",
"--fasta_directory",
required=True,
help="Directory containing FASTA files",
)
parser.add_argument(
"-t",
"--tbl_directory",
required=True,
help="Directory containing tbl result files",
)
parser.add_argument(
"-f",
"--all_fasta",
required=True,
help="FASTA format cds file of cadidate species",
)
parser.add_argument(
"-o",
"--output_directory",
required=True,
help="Directory to write output seqname",
)
parser.add_argument(
"-s",
"--species_name",
required=False,
help="Species name of candidate species",
)
args = parser.parse_args()
main(
args.fasta_directory,
args.tbl_directory,
args.output_directory,
args.all_fasta,
args.species_name,
)
@@ -1,215 +0,0 @@
#! /usr/bin/env python3
import os
import re
import argparse
from Bio import SeqIO
from pathlib import Path
def parse_fasta(fasta_file_path):
"""
Parse a FASTA file and return a list of sequence ids.
Args:
fasta_file_path: Path to the FASTA file
Returns:
list: List of sequence ids
"""
sequence_ids = []
try:
for record in SeqIO.parse(fasta_file_path, "fasta"):
sequence_ids.append(record.id)
except Exception as e:
print(f"Error parsing FASTA file {fasta_file_path}: {e}")
return sequence_ids
def parse_hmmer_tbl(tbl_file_path):
"""
Parse HMMER tbl format result file and extract best hit information
Args:
tbl_file_path: Path to the tbl file
Returns:
dict: Best hit information
"""
best_hit = {}
try:
with open(tbl_file_path, "r") as f:
for line in f:
# Skip comment lines
if line.startswith("#"):
continue
# Split line (tbl format is typically space or tab separated)
parts = re.split(r"\s+", line.strip())
if len(parts) < 5:
continue
# Extract key information: target name, E-value, score, etc.
# tbl format columns: target name, target accession, query name, query accession, E-value, score, etc.
target_name = parts[0]
e_value = float(parts[4]) # Full sequence E-value
# If it's a new sequence or we found a better hit (lower E-value)
if not best_hit.keys() or e_value < best_hit["e_value"]:
best_hit = {
"e_value": e_value,
"target_name": target_name,
}
except Exception as e:
print(f"Error parsing tbl file {tbl_file_path}: {e}")
return {}
return best_hit
def find_corresponding_files(fasta_dir, tbl_dir):
"""
Find corresponding FASTA and tbl file pairs
Args:
fasta_dir: Directory containing FASTA files
tbl_dir: Directory containing tbl result files
Returns:
list: List of (fasta_file_path, tbl_file_path) tuples
"""
file_pairs = []
# Get all FASTA files
fasta_files = {}
for fasta_path in Path(fasta_dir).glob("*.fa"):
stem = fasta_path.stem
fasta_files[stem] = fasta_path
# Find corresponding tbl files
for stem, fasta_path in fasta_files.items():
tbl_name = f"{stem}.fa.hmmsearch.tblout"
tbl_path = Path(tbl_dir) / tbl_name
if tbl_path.exists():
file_pairs.append((fasta_path, tbl_path))
else:
print(f"Warning: No corresponding tbl file found for {stem}")
return file_pairs
def add_best_hit_to_og_list(file_pair):
"""
Add best hit information to FASTA file
Args:
file_pair: Tuple of (fasta_path, tbl_path)
Returns:
tuple: (stem, seq_ids)
"""
fasta_path, tbl_path = file_pair
# Parse tbl file to get best hits
best_hit = parse_hmmer_tbl(tbl_path)
if not best_hit:
print(f"Warning: No valid hits found in {tbl_path}")
return fasta_path.stem, []
best_seq = best_hit["target_name"]
seq_ids = parse_fasta(fasta_path)
seq_ids.append(best_seq)
return fasta_path.stem, seq_ids
def process_all_files(fasta_dir, tbl_dir, output_file):
"""
Process all FASTA and tbl file pairs
Args:
fasta_dir: Directory containing FASTA files
tbl_dir: Directory containing tbl result files
output_file: Output file path
"""
print("Starting file processing...")
print(f"FASTA directory: {fasta_dir}")
print(f"tbl directory: {tbl_dir}")
print(f"Output file: {output_file}")
print("-" * 50)
og_list = {}
# Find corresponding file pairs
file_pairs = find_corresponding_files(fasta_dir, tbl_dir)
if not file_pairs:
print("No corresponding FASTA-tbl file pairs found")
return
print(f"Found {len(file_pairs)} file pairs to process")
# Process each file pair
for i, file_pair in enumerate(file_pairs, 1):
print(f"\nProcessing pair {i}/{len(file_pairs)}:")
stem, seq_ids = add_best_hit_to_og_list(file_pair)
if not seq_ids:
print(f"Skipping {stem} due to no valid hits")
continue
og_list[stem] = seq_ids
with open(output_file, "w") as out_f:
for og, ids in og_list.items():
out_f.write(f"{og}\t" + "\t".join(ids) + "\n")
print(f"\nProcessing completed! All results saved to: {output_file}")
def main(fasta_directory, tbl_directory, output_file):
"""
Main function - take paths and run processing
Args:
fasta_directory: Folder containing FASTA files
tbl_directory: Folder containing tbl result files
output_file: Output file path
"""
# Check if input directories exist
if not os.path.exists(fasta_directory):
print(f"Error: FASTA directory does not exist {fasta_directory}")
return
if not os.path.exists(tbl_directory):
print(f"Error: tbl directory does not exist {tbl_directory}")
return
# Process all files
process_all_files(fasta_directory, tbl_directory, output_file)
if __name__ == "__main__":
# Parse command-line arguments and call main
parser = argparse.ArgumentParser(
description="Add HMMER best hit into orthologs FASTA."
)
parser.add_argument(
"-f",
"--fasta_directory",
required=True,
help="Directory containing FASTA files",
)
parser.add_argument(
"-t",
"--tbl_directory",
required=True,
help="Directory containing tbl result files",
)
parser.add_argument(
"-o",
"--output_file",
required=True,
help="File to write output seqname",
)
args = parser.parse_args()
main(args.fasta_directory, args.tbl_directory, args.output_file)
+28
View File
@@ -0,0 +1,28 @@
#! /bin/bash
FS_LR=7
if [ "$#" -ne 3 ]; then
echo "Usage: $0 <reliable_seq> <less_reliable_seq> <stem>"
echo "Perform MACSE alignment on given sequences"
exit 1
fi
seq=$1
seq_lr=$2
stem=$3
{
echo "Command:"
echo "macse -prog alignSequences -seq $seq -seq_lr ${seq_lr}"
echo " -out_NT ${stem}.nal -out_AA ${stem}.pal"
echo " -optim 2 -max_refine_iter 3 -local_realign_init 0.2 -fs_lr $FS_LR"
} >alignSequences.log
macse -prog alignSequences \
-seq "$seq" -seq_lr "${seq_lr}" \
-out_NT "$stem".nal -out_AA "$stem".pal \
-optim 2 \
-max_refine_iter 3 \
-local_realign_init 0.2 \
-fs_lr $FS_LR \
>>alignSequences.log 2>&1
+30 -16
View File
@@ -7,41 +7,53 @@ Function: Rename sequences in FASTA file to format: [prefix@sequence_number]
import sys
import os
def rename_fasta_sequences(input_file, prefix, output_file=None):
"""
Rename sequence headers in a FASTA file
Parameters:
input_file: Input FASTA filename
prefix: Prefix for sequence names
output_file: Output filename (optional, defaults to input_file_renamed.fasta)
"""
# Set output filename
if output_file is None:
file_base, file_ext = os.path.splitext(input_file)
output_file = f"{file_base}_renamed{file_ext}"
match_tsv = f"{output_file}.tsv"
print(f"Input file: {input_file}")
print(f"Output file: {output_file}")
print(f"Naming format: {prefix}@mrna_<number>")
print(f"Match TSV file: {match_tsv}")
# Counter for sequences
seq_count = 0
try:
with open(input_file, 'r') as fin, open(output_file, 'w') as fout:
with (
open(input_file, "r") as fin,
open(output_file, "w") as fout,
open(match_tsv, "w") as tsvout,
):
tsvout.write("Original_Name\tNew_Name\n")
for line in fin:
if line.startswith('>'):
if line.startswith(">"):
# Sequence header line: rename it
seq_count += 1
new_name = f">{prefix}@mrna_{seq_count}\n"
fout.write(new_name)
original_name = line[1:].strip().split()[0]
new_name = f"{prefix}@mrna_{seq_count}\n"
fout.write(f">{new_name}")
tsvout.write(f"{original_name}\t{new_name}\n")
else:
# Sequence data line: write as-is
fout.write(line)
print(f"Successfully renamed {seq_count} sequences")
print(f"Input file: {input_file}")
print(f"Output file: {output_file}")
print(f"Naming format: {prefix}@mrna_number")
except FileNotFoundError:
print(f"Error: Input file '{input_file}' not found")
sys.exit(1)
@@ -49,23 +61,25 @@ def rename_fasta_sequences(input_file, prefix, output_file=None):
print(f"Error processing file: {e}")
sys.exit(1)
def main():
"""Main function"""
if len(sys.argv) < 3:
print("Usage: python script.py <fasta_file> <prefix> [output_file]")
print("Example: python script.py sequences.fasta Gene new_sequences.fasta")
sys.exit(1)
input_file = sys.argv[1]
prefix = sys.argv[2]
output_file = sys.argv[3] if len(sys.argv) > 3 else None
# Verify input file exists
if not os.path.isfile(input_file):
print(f"Error: File '{input_file}' does not exist")
sys.exit(1)
rename_fasta_sequences(input_file, prefix, output_file)
if __name__ == "__main__":
main()
+51
View File
@@ -0,0 +1,51 @@
#! /bin/bash
set -e
if [ "$#" -ne 4 ]; then
echo "Usage: $0 <ogs_dir> <outdir> <proteome> <threads>"
echo "search homologous sequences in <proteome> using HMMs built from orthogroup alignments"
exit 1
fi
ogs_dir=$(readlink -f "$1")
outdir=$2
proteome=$(readlink -f "$3")
threads=$4
mkdir -p "$outdir"
cd "$outdir" || exit 1
echo "Working directory: $(pwd)"
echo "Using OGS directory: $ogs_dir"
echo "Using $threads threads"
echo ""
echo "Starting orthogroup sequence alignment..."
mkdir -p msa
echo -n >mafft.cmds
for i in "$ogs_dir"/*.fa; do
j=$(basename "$i")
echo "linsi --quiet $i > msa/$j" >>mafft.cmds
done
xargs -t -P "$threads" -I cmd -a mafft.cmds bash -c "cmd"
echo "Orthogroup sequence alignment completed."
echo ""
echo "Starting HMM building from alignments..."
mkdir -p hmms
echo -n >hmmbuild.cmds
for i in msa/*.fa; do
j=$(basename "$i")
echo "hmmbuild -o hmms/${j}.hmmbuild.out --amino hmms/${j}.hmm $i" >>hmmbuild.cmds
done
xargs -t -P "$threads" -I cmd -a hmmbuild.cmds bash -c "cmd"
echo "HMM building completed."
echo ""
echo "Starting HMM search against other proteome..."
mkdir -p search
echo -n >hmmsearch.cmds
for i in hmms/*.hmm; do
j=$(basename "$i")
echo "hmmsearch --tblout search/${j}search.tblout $i $proteome > search/${j}search.rawout" >>hmmsearch.cmds
done
xargs -t -P "$threads" -I cmd -a hmmsearch.cmds bash -c "cmd"
echo "HMM search completed."
echo ""
echo "All steps completed successfully."
@@ -1,8 +0,0 @@
#! /usr/bin/env bash
mkdir -p msa
echo -n > mafft.cmds
for i in ogs/*.fa ; do
j=$(basename "$i")
echo "linsi --quiet $i > msa/$j" >> mafft.cmds
done
xargs -t -P 8 -I cmd -a mafft.cmds bash -c "cmd"
@@ -1,8 +0,0 @@
#! /usr/bin/env bash
mkdir -p hmms
echo -n > hmmbuild.cmds
for i in msa/*.fa ; do
j=$(basename "$i")
echo "hmmbuild -o hmms/${j}.hmmbuild.out --amino hmms/${j}.hmm $i" >> hmmbuild.cmds
done
xargs -t -P 8 -I cmd -a hmmbuild.cmds bash -c "cmd"
+34
View File
@@ -0,0 +1,34 @@
#! /bin/bash
set -e
SCRIPTS=${SCRIPTS:-"$PROJECTHOME/99.scripts"}
THREADS=${THREADS:-12}
if [ "$#" -ne 5 ]; then
echo "Usage: $0 <ogs_dir> <hmmsearch_result_dir> <all_cds.fa> <output_dir> <homolog_stem>"
echo "Integrate hmmsearch results to new orthologous groups directory and perform MACSE alignment"
exit 1
fi
ogs_dir=$(readlink -f "$1")
search_dir=$(readlink -f "$2")
all_cds=$(readlink -f "$3")
out_dir=$4
stem=$5
echo "Integrating hmmsearch results to new orthologous groups directory..."
python3 "$SCRIPTS"/miscs/hmmsearch_result_to_new_ogs_dir.py \
-d "$ogs_dir" \
-t "$search_dir" \
-f "$all_cds" \
-o "$out_dir" \
-s "$stem"
echo "Integration completed."
echo "Starting MACSE alignment of orthologous groups..."
echo -n >macse.cmds
for og_dir in "$out_dir"/ogs/*; do
j=$(basename "$og_dir")
echo "cd $og_dir && bash $SCRIPTS/miscs/macse.sh ${j}_${stem}.fa ${j}.fa $j" >>macse.cmds
done
xargs -t -P "$THREADS" -I cmd -a macse.cmds bash -c "cmd"
echo "MACSE alignment completed."
@@ -1,8 +0,0 @@
#! /usr/bin/env bash
mkdir -p hmmsearch
echo -n > hmmsearch.cmds
for i in hmms/*.hmm ; do
j=$(basename "$i")
echo "hmmsearch --tblout hmmsearch/${j}search.tblout $i ../../01.reference/Zju.pep.fa > hmmsearch/${j}search.rawout" >> hmmsearch.cmds
done
xargs -t -P 8 -I cmd -a hmmsearch.cmds bash -c "cmd"
@@ -1,8 +0,0 @@
#! /usr/bin/env bash
mkdir -p pep_aln
echo -n > mafft.cmds
for i in raw_ogs/pep/*.fa; do
j=$(basename "$i")
echo "linsi --quiet $i > pep_aln/${j/.fa/.pal}" >> mafft.cmds
done
xargs -t -P 8 -I cmd -a mafft.cmds bash -c "cmd"
@@ -1,8 +0,0 @@
#! /usr/bin/env bash
mkdir -p cds_aln
echo -n > pal2nal.cmds
for i in pep_aln/*.pal; do
j=$(basename "$i")
echo "pal2nal.pl $i raw_ogs/cds/${j/.pal/.fa} -output fasta > cds_aln/${j/.pal/.nal}" >> pal2nal.cmds
done
xargs -t -P 8 -I cmd -a pal2nal.cmds bash -c "cmd"
@@ -94,11 +94,18 @@ def concatenate_fasta_files(fasta_files, output_file):
print(f"Total output sequence length: {len(concatenated_sequences[0].seq)}.")
def get_fasta_files_from_directory(directory, extensions):
def get_fasta_files_from_directory(directory, extensions, list_file=None):
"""
get all FASTA files from a directory with specified extensions
"""
fasta_files = []
if list_file:
with open(list_file, "r") as lf:
for line in lf:
filepath = os.path.join(directory, line.strip())
if os.path.isfile(filepath):
fasta_files.append(filepath)
return sorted(fasta_files)
for filename in os.listdir(directory):
if any(filename.endswith(ext) for ext in extensions):
fasta_files.append(os.path.join(directory, filename))
@@ -119,12 +126,15 @@ def main():
default=[".fasta", ".fa", ".fna"],
help="FASTA file extensions to look for in directory",
)
parser.add_argument("-l", "--list", help="List of input FASTA files", default=None)
args = parser.parse_args()
# 获取输入文件
if args.directory:
fasta_files = get_fasta_files_from_directory(args.directory, args.extensions)
fasta_files = get_fasta_files_from_directory(
args.directory, args.extensions, args.list
)
if not fasta_files:
print(
f"Cannot find FASTA files in {args.directory} with extensions {args.extensions}"
@@ -137,7 +147,7 @@ def main():
return
print(f"Found {len(fasta_files)} FASTA files:")
# Perform concatenation
concatenate_fasta_files(fasta_files, args.output)
+15
View File
@@ -0,0 +1,15 @@
#! /usr/bash
if [ "$#" -ne 5 ]; then
echo "Usage: $0 <reference_genome> <fastq_1> <fastq_2> <output_directory> <stem>"
exit 1
fi
ref=$1
fq1=$2
fq2=$3
outdir=$4
stem=$5
mkdir -p "$outdir"
hisat -p 4 --dta -x "$ref" -1 "$fq1" -2 "$fq2" -S "${outdir}/${stem}.sam"
samtools view -b -@ 4 "${outdir}/${stem}.sam" | samtools sort -@ 4 -o "${outdir}/${stem}.sorted.bam" --write-index
rm "${outdir}/${stem}.sam"
echo "Mapping completed. Sorted BAM file is at ${outdir}/${stem}.sorted.bam"
@@ -0,0 +1,31 @@
#! /bin/bash
set -e
SCRIPTS=${SCRIPTS:-"$PROJECTHOME/99.scripts"}
MAX_MEMORY=${MAX_MEMORY:-"20G"}
VIRIDI=${VIRIDI:-"$PROJECTHOME/01.reference/viridiplantae_odb12/"}
ROSALES=${ROSALES:-"$PROJECTHOME/01.reference/rosales_odb12/"}
if [ "$#" -ne 4 ]; then
echo "Usage: $0 <reads_1.fastq> <reads_2.fastq> <stem> <threads>"
echo "Perform de novo transcriptome assembly using Trinity"
exit 1
fi
fq1=$1
fq2=$2
stem=$3
outdir="$stem"_trinity_out_dir
THREADS=$4
# Run Trinity for de novo transcriptome assembly
Trinity --seqType fq --left "$fq1" --right "$fq2" --CPU "$THREADS" --max_memory "$MAX_MEMORY" --output "$outdir"
# Get Longest isoform per gene
perl "$SCRIPTS"/trinity_utils/util/misc/get_longest_isoform_seq_per_trinity_gene.pl "$outdir.Trinity.fasta" >"$outdir".longest_isoform.fasta
# BUSCO assessment
busco -i "$outdir".longest_isoform.fasta -l "$VIRIDI" -m tran --cpu "$THREADS" -o "$outdir"_busco_viridi -f
busco -i "$outdir".longest_isoform.fasta -l "$ROSALES" -m tran --cpu "$THREADS" -o "$outdir"_busco_rosales -f
# Length Statistics
TrinityStats.pl "$outdir.Trinity.fasta" >"$outdir".Trinity.fasta.length_stat.txt
# Clear temporary directory
rm -rf "$outdir"
@@ -0,0 +1,37 @@
#! /bin/bash
set -e
MAX_MEMORY=${MAX_MEMORY:-"50G"}
VIRIDI=${VIRIDI:-"$PROJECTHOME/01.reference/viridiplantae_odb12/"}
ROSALES=${ROSALES:-"$PROJECTHOME/01.reference/rosales_odb12/"}
SCRIPTS=${SCRIPTS:-"$PROJECTHOME/99.scripts"}
if [ "$#" -ne 5 ]; then
echo "Usage: $0 <reads_1.fastq> <reads_2.fastq> <ref> <stem> <threads>"
echo "Perform reference-guided transcriptome assembly using Hisat2 and Trinity"
exit 1
fi
fq1=$1
fq2=$2
ref=$3
stem=$4
outdir="$stem"_trinity_out_dir
THREADS=$5
# Run Hisat2 for reads mapping to reference genome
hisat2 -p "$THREADS" --dta -x "$ref" -1 "$fq1" -2 "$fq2" -S "$stem".sam
samtools view -b -@ "$THREADS" -o "$stem".raw.bam "$stem".sam
samtools sort -@ "$THREADS" -o "$stem".sorted.bam "$stem".raw.bam
samtools index "$stem".sorted.bam
rm "$stem".sam "$stem".raw.bam
# Run Trinity for de novo transcriptome assembly
Trinity --genome_guided_bam "$stem".sorted.bam --genome_guided_max_intron 10000 --max_memory "$MAX_MEMORY" --CPU "$THREADS" --output "$outdir"
# Get Longest isoform per gene
perl "$SCRIPTS"/trinity_utils/util/misc/get_longest_isoform_seq_per_trinity_gene.pl "$outdir/Trinity-GG.fasta" >"$outdir/longest_isoform.fasta"
# BUSCO assessment
busco -i "$outdir"/longest_isoform.fasta -l "$VIRIDI" -m tran --cpu "$THREADS" -o "$outdir"/busco_viridi -f
busco -i "$outdir"/longest_isoform.fasta -l "$ROSALES" -m tran --cpu "$THREADS" -o "$outdir"/busco_rosales -f
# Length Statistics
TrinityStats.pl "$outdir"/Trinity-GG.fasta >"$outdir"/length_stat.txt
@@ -0,0 +1,18 @@
#! /bin/bash
set -e
TMP=${TMP:-"$PROJECTHOME/tmp"}
if [ "$#" -ne 3 ]; then
echo "Usage: $0 <transcripts_fasta> <swissprot_database> <output_directory>"
echo "Predict coding sequences (CDS) from transcripts using TD2 and MMseqs2"
exit 1
fi
transcripts=$1
sprot=$2
outdir=$3
mkdir -p "$outdir"
TD2.LongOrfs -t "$transcripts" --precise -@ 8 -O "$outdir"
mmseqs easy-search "$outdir/longest_orfs.pep" "$sprot" "$outdir/mmseqs.m8" "$TMP" -s 7.0 --threads 16
TD2.Predict -t "$transcripts" --precise -O "$outdir" --retain-mmseqs-hits "$outdir/mmseqs.m8"
echo "CDS prediction completed. Results are in $outdir"
@@ -0,0 +1,25 @@
#! /bin/bash
set -e
SCRIPTS=${SCRIPTS:-"$PROJECTHOME/99.scripts"}
if [ "$#" -ne 3 ]; then
echo "Usage: $0 <input_dir> <output_dir> <extension>"
echo "Extract longest isoform per gene and rename sequences"
exit 1
fi
indir=$1
outdir=$2
ext=$3
mkdir -p "$outdir"
# Process each file in the input directory with the specified extension
for td_cds in "$indir"/*."$ext"; do
stem=$(basename "$td_cds" ."$ext")
echo "Processing $td_cds($stem) ..."
echo "perl $SCRIPTS/trinity_utils/util/misc/get_longest_isoform_seq_per_trinity_gene.pl $td_cds > $outdir/$stem.longest_isoform.fa"
perl "$SCRIPTS"/trinity_utils/util/misc/get_longest_isoform_seq_per_trinity_gene.pl "$td_cds" >"$outdir"/"$stem".longest_isoform.fa
echo "$SCRIPTS/rename_trinity_fasta.py $outdir/$stem.longest_isoform.fa $stem $outdir/$stem.full_cds.fa"
"$SCRIPTS"/miscs/rename_trinity_fasta.py "$outdir"/"$stem".longest_isoform.fa "$stem" "$outdir"/"$stem".full_cds.fa
echo "Done."
done
@@ -0,0 +1,27 @@
#! /bin/bash
set -e
SCRIPTS=${SCRIPTS:-"$PROJECTHOME/99.scripts"}
IDENTITY=${IDENTITY:-0.99}
THREADS=${THREADS:-6}S
if [ "$#" -ne 3 ]; then
echo "Usage: $0 <input_dir> <output_dir> <extension>"
echo "Reduce redundancy of CDS files using cd-hit-est"
exit 1
fi
indir=$1
outdir=$2
ext=$3
mkdir -p "$outdir"
# Process each file in the input directory with the specified extension
for cds in "$indir"/*."$ext"; do
stem=$(basename "$cds" ."$ext")
echo "Processing $cds($stem) ..."
echo "cd-hit-est -i $cds -o $outdir/$stem.cds_rr.fa -c $IDENTITY -n 10 -r 0 -T $THREADS"
cd-hit-est -i "$cds" -o "$outdir/$stem".cds_rr.fa -c "$IDENTITY" -n 10 -r 0 -T "$THREADS"
echo "seqkit translate $outdir/$stem.cds_rr.fa > $outdir/$stem.prot_rr.fa"
seqkit translate "$outdir/$stem".cds_rr.fa >"$outdir/$stem".prot_rr.fa
echo "Done."
done