-
Notifications
You must be signed in to change notification settings - Fork 0
Transcript assembly commands
swarbred edited this page Apr 14, 2026
·
26 revisions
These commands demonstrate a simple RNA-seq transcript assembly workflow using HISAT2, StringTie, Scallop, Mikado Compare, and Portcullis.
Aim of this exercise: map RNA-seq reads to the genome, assemble transcripts with two different tools, compare those assemblies to each other and to a reference annotation, and explore how splice-junction filtering affects transcript evidence.
cd /home/train/Annotation_workshop/Transcriptome_assemblyexport genome=Inputs/Reference/Athaliana_447_TAIR10_Chr3_clean.faNotes
-
cdmoves into the expected working directory. -
export genome=...stores the genome path in a shell variable so it can be reused later. - This makes later commands easier to read and edit.
2 Build Hisat2 index
hisat2-build -h(
rm -rf Hisat2 Stringtie Scallop Assemblies Mikado_Compare Portcullis mikado_compare* *portcullis*
mkdir -p Hisat2/db
hisat2-build \
$genome \
Hisat2/db/Athaliana_447_TAIR10_Chr3_clean \
> Hisat2/index.log 2>&1
)Notes
-
rm -rf ...removes previous outputs so the exercise starts cleanly. -
hisat2-buildcreates an index from the genome FASTA. - The index basename here is
Hisat2/db/Athaliana_447_TAIR10_Chr3_clean. - The log is written to
Hisat2/index.log.
(
mkdir -p Hisat2/SRR5956436
hisat2 \
--max-intronlen 50000 \
--rna-strandness RF \
--dta -p 2 \
-x Hisat2/db/Athaliana_447_TAIR10_Chr3_clean \
-1 Inputs/Reads/SRR5956436/*R1.*fastq.gz \
-2 Inputs/Reads/SRR5956436/*R2.*fastq.gz \
-S Hisat2/SRR5956436/Hisat2.sam
)Notes
- This aligns one paired-end RNA-seq sample to the genome.
-
-xpoints to the HISAT2 index basename. -
--max-intronlen 50000sets the maximum intron size HISAT2 will consider. -
--rna-strandness RFspecifies the stranded library type. -
--dtameans the alignments are tailored for downstream transcript assembly. -
-Swrites SAM output to a file.
(
mkdir -p Hisat2/SRR5956436
hisat2 \
--max-intronlen 50000 \
--rna-strandness RF \
--dta -p 2 \
-x Hisat2/db/Athaliana_447_TAIR10_Chr3_clean \
-1 Inputs/Reads/SRR5956436/*R1.*fastq.gz \
-2 Inputs/Reads/SRR5956436/*R2.*fastq.gz |
samtools sort -@ 2 -o Hisat2/SRR5956436/Hisat2.bam && \
samtools index Hisat2/SRR5956436/Hisat2.bam
)Notes
- This pipes HISAT2 output directly into
samtools sort. - The result is a coordinate-sorted BAM file.
-
samtools indexcreates a.baiindex so the BAM can be accessed by genomic position.
(
for folder in Inputs/Reads/SR*; do
echo -ne "\n\n## Running Hisat2 on sample ${folder} ... " && \
folder=$(basename $folder) && mkdir -p Hisat2/${folder} && \
hisat2 \
--max-intronlen 50000 --rna-strandness RF \
--dta -p 2 \
-x Hisat2/db/Athaliana_447_TAIR10_Chr3_clean \
-1 Inputs/Reads/${folder}/*R1.*fastq.gz \
-2 Inputs/Reads/${folder}/*R2.*fastq.gz |
samtools sort -@ 2 -o Hisat2/${folder}/Hisat2.bam
done
)Notes
- This applies the same alignment procedure to all samples.
- Each sample gets its own output folder in
Hisat2/.
mkdir -p {Stringtie,Scallop}/SRR5956436 4.1 Stringtie sample SRR5956436
(
stringtie Hisat2/SRR5956436/Hisat2.bam \
-o Stringtie/SRR5956436/SRR5956436.gtf \
> Stringtie/SRR5956436/stringtie.log 2>&1
)Notes
- StringTie assembles transcripts from the aligned reads in the BAM file.
- The output is a GTF file containing transcript models.
4.2 Scallop sample SRR5956436
(
scallop -i Hisat2/SRR5956436/Hisat2.bam \
-o Scallop/SRR5956436/SRR5956436.gtf \
> Scallop/SRR5956436/scallop.log 2>&1
)Notes
- Scallop is another transcript assembler.
- It uses the same BAM input, but may produce different transcript models from StringTie.
Try yourself
- Does Scallop predict more transcripts than StringTie?
- Are the extra predictions mostly multi-exon or single-exon?
(
for folder in Inputs/Reads/SRR*; do
echo -ne "\n\n## Running stringtie on sample ${folder} ... " && \
folder=$(basename ${folder}) && mkdir -p Assemblies Stringtie/${folder} && \
stringtie \
Hisat2/${folder}/Hisat2.bam \
-l ${folder}_STRG \
-o Stringtie/${folder}/${folder}.gtf \
> Stringtie/${folder}/stringtie.log 2>&1 && \
cp Stringtie/${folder}/${folder}.gtf Assemblies/stringtie-${folder}.gtf && \
echo done
done
)Notes
-
-l ${folder}_STRGadds a sample-specific label prefix to transcript IDs (without this assemblies would share IDs). - GTF files are copied into
Assemblies/for easier downstream comparison.
(
for folder in Inputs/Reads/SRR*; do
echo -ne "\n\n## Running scallop on sample ${folder} ... " && \
folder=$(basename ${folder}) && mkdir -p Assemblies Scallop/${folder} && \
scallop \
-i Hisat2/${folder}/Hisat2.bam \
-o Scallop/${folder}/${folder}.gtf \
> Scallop/${folder}/scallop.log 2>&1 && \
cp Scallop/${folder}/${folder}.gtf Assemblies/scallop-${folder}.gtf && \
echo done
done
)Try yourself
- Compare transcript counts across samples.
- Which assembler seems more conservative?
(
mkdir -p Mikado_Compare
mikado compare \
-r Assemblies/stringtie-SRR5956436.gtf \
-p Assemblies/scallop-SRR5956436.gtf \
-o Mikado_Compare/mikado_compare_stringtie-SRR5956436_v_scallop-SRR5956436
)Notes
- This compares transcript models from the two assemblers for the same sample.
- Useful for showing how different assemblers may make different choices.
Stringtie assemblies vs reference annotation
(
mkdir -p Mikado_Compare
for file in Assemblies/str*gtf; do
echo -e "\n\n## $file" && \
outfile=$(basename ${file} .gtf) && \
mikado compare \
-r Inputs/Ref_Annotation/Athaliana_447_Araport11.gene_exons.regionA.gtf \
-p $file \
-o Mikado_Compare/mikado_compare_ref_v_${outfile}
done
)Scallop assemblies vs reference annotation
(
mkdir -p Mikado_Compare
for file in Assemblies/sca*gtf; do
echo -e "\n\n## $file" && \
outfile=$(basename ${file} .gtf) && \
mikado compare \
-r Inputs/Ref_Annotation/Athaliana_447_Araport11.gene_exons.regionA.gtf \
-p $file \
-o Mikado_Compare/mikado_compare_ref_v_${outfile}
done
)Notes
- Each assembly is compared against the reference annotation.
- This helps assess how well the assemblies recover known transcript structures.
Try yourself
- Which assembler matches the reference better overall?
- Do some samples recover more of the annotation than others?
(
assemblies=(Assemblies/str*gtf)
echo -ne "\n\n## Running stringtie --merge on ${assemblies[@]}\n"
mkdir -p Assemblies/Stringtie_Merge
stringtie \
--merge "${assemblies[@]}" \
-o Assemblies/Stringtie_Merge/merged_stringtie.gtf
)Notes
-
stringtie --mergecombines transcript models from multiple samples into one merged set.
Try yourself
- Does the merged set contain more transcripts than any single sample?
- Check out the merge usage mode in the stringtie help (
stringtie -h)
cat Assemblies/str*gtf | gffread -T -o Assemblies/Stringtie_Merge/all_stringtie.gtfNotes
- This concatenates all StringTie GTFs and converts them into a single GTF.
- It does not intelligently merge transcript structures.
cat Assemblies/str*gtf | gffread -T -M -K -Q -o Assemblies/Stringtie_Merge/all_stringtie_clustered.gtfNotes
- This is a more aggressive attempt to cluster or collapse related transcript models.
- It is useful for comparing different ways of combining assemblies.
(
mkdir -p Assemblies/Stringtie_Merge/Mikado_Compare
for file in Assemblies/Stringtie_Merge/*gtf; do
echo -e "\n\n## $file"
outfile=$(basename ${file} .gtf)
mikado compare \
-r Inputs/Ref_Annotation/Athaliana_447_Araport11.gene_exons.regionA.gtf \
-p $file \
-o Assemblies/Stringtie_Merge/Mikado_Compare/mikado_compare_ref_v_${outfile}
done
)Notes
- This compares the merged, concatenated, and clustered transcript sets to the reference annotation.
Try yourself
- Does merging improve reference recovery?
- Does merging with the default parameters lose some sensitivity compared to the concatenated transcripts ?
- Try rerunning the merging with different merging options e.g. lowering -F or -T and rerunning the comparison to the reference, do we increase sn, pr or F1?
7.1 Realign reads omitting the --dta option (it is generally sensible for annotation purposes to run with the --dta option we are only removing this option for demonstration purposes as this is a small toy dataset)
(
for folder in Inputs/Reads/SR*; do
echo -e "\n\n## Running Hisat2 on sample ${folder} ... " && \
folder=$(basename $folder) && \
mkdir -p Portcullis/Hisat2/${folder} && \
hisat2 \
--max-intronlen 50000 \
--rna-strandness RF -p 2 \
-x Hisat2/db/Athaliana_447_TAIR10_Chr3_clean \
-1 Inputs/Reads/${folder}/*R1.*fastq.gz \
-2 Inputs/Reads/${folder}/*R2.*fastq.gz |
samtools sort -@ 2 -o Portcullis/Hisat2/${folder}/Hisat2.bam
done
)Notes
-
--dtais omitted here only for demonstration purposes. - In a real annotation workflow, using
--dtais usually sensible for transcript assembly. - Here the main aim is to generate alignments to explore Portcullis junction filtering.
(
for folder in Inputs/Reads/SRR*; do
echo -ne "\n\n## Running portcullis on sample ${folder} ... " && \
cd Portcullis/Hisat2/$(basename ${folder}) && \
rm -rf portcullis_out && \
portcullis full \
--keep_temp --exon_gff --save_bad \
../../../Inputs/Reference/Athaliana_447_TAIR10_Chr3_clean.fa \
Hisat2.bam > portcullis.log 2>&1 && \
cd ../../.. && \
echo done
done
)Notes
- Portcullis evaluates splice junctions and separates likely good junctions from likely false ones.
-
--save_badkeeps failed junctions for later comparison.
(
for i in Portcullis/Hisat2/SRR7947124; do
sample=$(basename $i)
echo -e "\n\n## Processing .... " $sample
rm -rf $i/Mikado_compare
mkdir -p $i/Mikado_compare
cp $i/portcullis_out/2-junc/portcullis_all.junctions.exon.gff3 \
$i/Mikado_compare/${sample}_portcullis_all.junctions.exon.gff3
cp $i/portcullis_out/3-filt/portcullis_filtered.pass.junctions.exon.gff3 \
$i/Mikado_compare/${sample}_portcullis_filtered.pass.junctions.exon.gff3
for f in $i/Mikado_compare/*gff3; do
cat $f | sed -e 's/match\t/transcript\t/g' -e 's/match_part\t/exon\t/g' > $i/Mikado_compare/$(basename $f .gff3).fix.gff3
mikado compare \
-r Inputs/Ref_Annotation/Athaliana_447_Araport11.gene_exons.regionA.gtf \
-p $i/Mikado_compare/$(basename $f .gff3).fix.gff3 \
-o $i/Mikado_compare/mikado_compare_$(basename $f)
done
done
)paste Portcullis/Hisat2/SRR7947124/Mikado_compare/mikado_compare_SRR7947124_portcullis_all.junctions.exon.gff3.stats \
Portcullis/Hisat2/SRR7947124/Mikado_compare/mikado_compare_SRR7947124_portcullis_filtered.pass.junctions.exon.gff3.statsNotes
- This compares all detected junctions versus only pass junctions for one sample.
- The
sedstep changes feature names so Mikado Compare can treat them more like transcript/exon features.
Try yourself
- Does using only pass junctions improve agreement with the reference?
- Is the improvement mainly in precision, sensitivity, or both?
(
for i in Portcullis/Hisat2/*; do
sample=$(basename $i)
echo -e "\n\n## Processing .... " $sample
rm -rf $i/Mikado_compare
mkdir -p $i/Mikado_compare
cp $i/portcullis_out/2-junc/portcullis_all.junctions.exon.gff3 \
$i/Mikado_compare/${sample}_portcullis_all.junctions.exon.gff3
cp $i/portcullis_out/3-filt/portcullis_filtered.pass.junctions.exon.gff3 \
$i/Mikado_compare/${sample}_portcullis_filtered.pass.junctions.exon.gff3
for f in $i/Mikado_compare/*gff3; do
cat $f | sed -e 's/match\t/transcript\t/g' -e 's/match_part\t/exon\t/g' > $i/Mikado_compare/$(basename $f .gff3).fix.gff3
mikado compare \
-r Inputs/Ref_Annotation/Athaliana_447_Araport11.gene_exons.regionA.gtf \
-p $i/Mikado_compare/$(basename $f .gff3).fix.gff3 \
-o $i/Mikado_compare/mikado_compare_$(basename $f)
done
done
)(
junctools set --operator max \
-o Portcullis/Hisat2/portcullis_pass_junctions.bed \
union Portcullis/Hisat2/*/portcullis_out/3-filt/portcullis_filtered.pass.junctions.bed && \
junctools set --operator max \
-o Portcullis/Hisat2/portcullis_fail_junctions.bed \
union Portcullis/Hisat2/*/portcullis_out/3-filt/portcullis_filtered.fail.junctions.bed
)(
junctools convert -if bed -of egff \
-o Portcullis/Hisat2/portcullis_pass_junctions.gff \
Portcullis/Hisat2/portcullis_pass_junctions.bed && \
junctools convert -if bed -of egff \
-o Portcullis/Hisat2/portcullis_fail_junctions.gff \
Portcullis/Hisat2/portcullis_fail_junctions.bed
)To clean up the directory to the original starting files
rm -rf Stringtie Scallop Mikado_Compare Assemblies SRR5956436* mikado_compare_* Hisat2 Portcullis- Workshop Wiki Home
- Basic Unix Command Guide
- Transcript assembly commands
- Mikado commands
- Annotation liftover commands
- Augustus
- Tiberius commands
- Helixer commands
- GALBA commands
- BRAKER3 commands
- Minos commands
- EVidenceModeler (EVM) commands
- Annotation Web Apollo Browser
- Workshop data locations
- Software tools used
- Guacamole tips
- Troubleshooting