This notebook will utilize gffread (Pertea and Pertea 2020) to create an A.pulchras GTF file from the A.pulchra genome GFF, which is needed for downstream analysis with HISAT2; specifically for identification of exons and splice sites.

1 Create a Bash variables file

This allows usage of Bash variables across R Markdown chunks.

{
echo "#### Assign Variables ####"
echo ""

echo "# Data directories"
echo 'export timeseries_dir=/home/shared/8TB_HDD_01/sam/gitrepos/urol-e5/timeseries_molecular'
echo 'export genome_dir="${timeseries_dir}/D-Apul/data"'
echo 'export output_dir_top=${timeseries_dir}/D-Apul/output/02.00-D-Apul-RNAseq-gff-to-gtf'
echo ""

echo "# Input/output files"

echo 'export genome_gff="${genome_dir}/Apulchra-genome.gff"'
echo 'export transcripts_gtf="Apulchra-genome.gtf"'

echo "# Paths to programs"
echo 'export programs_dir="/home/shared"'
echo 'export gffread="${programs_dir}/gffread-0.12.7.Linux_x86_64/gffread"'

echo "# Set number of CPUs to use"
echo 'export threads=40'
echo ""


echo "# Programs associative array"
echo "declare -A programs_array"
echo "programs_array=("
echo '[gffread]="${gffread}" \'
echo ")"
echo ""

echo "# Print formatting"
echo 'export line="--------------------------------------------------------"'
echo ""
} > .bashvars

cat .bashvars
#### Assign Variables ####

# Data directories
export timeseries_dir=/home/shared/8TB_HDD_01/sam/gitrepos/urol-e5/timeseries_molecular
export genome_dir="${timeseries_dir}/D-Apul/data"
export output_dir_top=${timeseries_dir}/D-Apul/output/02.00-D-Apul-RNAseq-gff-to-gtf

# Input/output files
export genome_gff="${genome_dir}/Apulchra-genome.gff"
export transcripts_gtf="Apulchra-genome.gtf"
# Paths to programs
export programs_dir="/home/shared"
export gffread="${programs_dir}/gffread-0.12.7.Linux_x86_64/gffread"
# Set number of CPUs to use
export threads=40

# Programs associative array
declare -A programs_array
programs_array=(
[gffread]="${gffread}" \
)

# Print formatting
export line="--------------------------------------------------------"

2 Preview and Validate Genome GFF

2.1 Inspect GFF

# Load bash variables into memory
source .bashvars

# Make directories, if they don't exist
mkdir --parents "${output_dir_top}"

head -n 20 "${genome_gff}"
##gff-version 3
ntLink_0    funannotate gene    1105    7056    .   +   .   ID=FUN_000001;
ntLink_0    funannotate mRNA    1105    7056    .   +   .   ID=FUN_000001-T1;Parent=FUN_000001;product=hypothetical protein;
ntLink_0    funannotate exon    1105    1188    .   +   .   ID=FUN_000001-T1.exon1;Parent=FUN_000001-T1;
ntLink_0    funannotate exon    1861    1941    .   +   .   ID=FUN_000001-T1.exon2;Parent=FUN_000001-T1;
ntLink_0    funannotate exon    2762    2839    .   +   .   ID=FUN_000001-T1.exon3;Parent=FUN_000001-T1;
ntLink_0    funannotate exon    5044    7056    .   +   .   ID=FUN_000001-T1.exon4;Parent=FUN_000001-T1;
ntLink_0    funannotate CDS 1105    1188    .   +   0   ID=FUN_000001-T1.cds;Parent=FUN_000001-T1;
ntLink_0    funannotate CDS 1861    1941    .   +   0   ID=FUN_000001-T1.cds;Parent=FUN_000001-T1;
ntLink_0    funannotate CDS 2762    2839    .   +   0   ID=FUN_000001-T1.cds;Parent=FUN_000001-T1;
ntLink_0    funannotate CDS 5044    7056    .   +   0   ID=FUN_000001-T1.cds;Parent=FUN_000001-T1;
ntLink_0    funannotate gene    10215   15286   .   +   .   ID=FUN_000002;
ntLink_0    funannotate mRNA    10215   15286   .   +   .   ID=FUN_000002-T1;Parent=FUN_000002;product=hypothetical protein;
ntLink_0    funannotate exon    10215   10413   .   +   .   ID=FUN_000002-T1.exon1;Parent=FUN_000002-T1;
ntLink_0    funannotate exon    10614   10676   .   +   .   ID=FUN_000002-T1.exon2;Parent=FUN_000002-T1;
ntLink_0    funannotate exon    11272   11316   .   +   .   ID=FUN_000002-T1.exon3;Parent=FUN_000002-T1;
ntLink_0    funannotate exon    11518   11591   .   +   .   ID=FUN_000002-T1.exon4;Parent=FUN_000002-T1;
ntLink_0    funannotate exon    12241   12501   .   +   .   ID=FUN_000002-T1.exon5;Parent=FUN_000002-T1;
ntLink_0    funannotate exon    13074   14383   .   +   .   ID=FUN_000002-T1.exon6;Parent=FUN_000002-T1;
ntLink_0    funannotate exon    14722   14900   .   +   .   ID=FUN_000002-T1.exon7;Parent=FUN_000002-T1;

2.2 Valdiate GFF

This identifies if there are rows with >9 fields (which there shouldn’t be in a GFF3).

Additionally, it provides a preview of all rows lengths identified.

# Load bash variables into memory
source .bashvars

# Capture number of fields (NF) in each row in array.
field_count_array=($(awk -F "\t" '{print NF}' "${genome_gff}" | sort --unique))


# Check array contents
echo "List of number of fields in ${genome_gff}:"
echo ""
for field_count in "${field_count_array[@]}"
do
  echo "${field_count}"
done

echo ""
echo "${line}"
echo ""

# Preview of each line "type" with a given number of fields
# Check array contents
echo ""
for field_count in "${field_count_array[@]}"
do
  echo "Preview of lines with ${field_count} field(s):"
  echo ""
  awk \
    -v field_count="${field_count}" \
    -F "\t" \
    'NF == field_count' \
    "${genome_gff}" \
    | head
  echo ""
  echo "${line}"
  echo ""
done
List of number of fields in /home/shared/8TB_HDD_01/sam/gitrepos/urol-e5/timeseries_molecular/D-Apul/data/Apulchra-genome.gff:

1
9

--------------------------------------------------------


Preview of lines with 1 field(s):

##gff-version 3

--------------------------------------------------------

Preview of lines with 9 field(s):

ntLink_0    funannotate gene    1105    7056    .   +   .   ID=FUN_000001;
ntLink_0    funannotate mRNA    1105    7056    .   +   .   ID=FUN_000001-T1;Parent=FUN_000001;product=hypothetical protein;
ntLink_0    funannotate exon    1105    1188    .   +   .   ID=FUN_000001-T1.exon1;Parent=FUN_000001-T1;
ntLink_0    funannotate exon    1861    1941    .   +   .   ID=FUN_000001-T1.exon2;Parent=FUN_000001-T1;
ntLink_0    funannotate exon    2762    2839    .   +   .   ID=FUN_000001-T1.exon3;Parent=FUN_000001-T1;
ntLink_0    funannotate exon    5044    7056    .   +   .   ID=FUN_000001-T1.exon4;Parent=FUN_000001-T1;
ntLink_0    funannotate CDS 1105    1188    .   +   0   ID=FUN_000001-T1.cds;Parent=FUN_000001-T1;
ntLink_0    funannotate CDS 1861    1941    .   +   0   ID=FUN_000001-T1.cds;Parent=FUN_000001-T1;
ntLink_0    funannotate CDS 2762    2839    .   +   0   ID=FUN_000001-T1.cds;Parent=FUN_000001-T1;
ntLink_0    funannotate CDS 5044    7056    .   +   0   ID=FUN_000001-T1.cds;Parent=FUN_000001-T1;

--------------------------------------------------------

Great! This looks like a valid GFF. Can proceed with GTF generation.

3 Generate GTF

# Load bash variables into memory
source .bashvars

${programs_array[gffread]} -E \
"${genome_gff}" -T \
1> ${output_dir_top}/"${transcripts_gtf}" \
2> ${output_dir_top}/gffread-gff_to_gtf.stderr

4 Inspect GTF

# Load bash variables into memory
source .bashvars

head ${output_dir_top}/"${transcripts_gtf}"
ntLink_0    funannotate transcript  1105    7056    .   +   .   transcript_id "FUN_000001-T1"; gene_id "FUN_000001"
ntLink_0    funannotate exon    1105    1188    .   +   .   transcript_id "FUN_000001-T1"; gene_id "FUN_000001";
ntLink_0    funannotate exon    1861    1941    .   +   .   transcript_id "FUN_000001-T1"; gene_id "FUN_000001";
ntLink_0    funannotate exon    2762    2839    .   +   .   transcript_id "FUN_000001-T1"; gene_id "FUN_000001";
ntLink_0    funannotate exon    5044    7056    .   +   .   transcript_id "FUN_000001-T1"; gene_id "FUN_000001";
ntLink_0    funannotate CDS 1105    1188    .   +   0   transcript_id "FUN_000001-T1"; gene_id "FUN_000001";
ntLink_0    funannotate CDS 1861    1941    .   +   0   transcript_id "FUN_000001-T1"; gene_id "FUN_000001";
ntLink_0    funannotate CDS 2762    2839    .   +   0   transcript_id "FUN_000001-T1"; gene_id "FUN_000001";
ntLink_0    funannotate CDS 5044    7056    .   +   0   transcript_id "FUN_000001-T1"; gene_id "FUN_000001";
ntLink_0    funannotate transcript  10215   15286   .   +   .   transcript_id "FUN_000002-T1"; gene_id "FUN_000002"

4.1 Copy GTF to D-Apul/data

To help make this easier to locate, will copy to the D-Apul/data directory, which also contains the genome FastA, genome FastA index, and the genome GFF files.

# Load bash variables into memory
source .bashvars

cp ${output_dir_top}/"${transcripts_gtf}" "${genome_dir}"
Pertea, Geo, and Mihaela Pertea. 2020. “GFF Utilities: GffRead and GffCompare.” F1000Research 9 (April): 304. https://doi.org/10.12688/f1000research.23297.1.
LS0tCnRpdGxlOiAiMDIuMDAtRC1BcHVsLVJOQXNlcS1nZmYtdG8tZ3RmIgphdXRob3I6ICJTYW0gV2hpdGUiCmRhdGU6ICIyMDI0LTEwLTA4IgpvdXRwdXQ6IAogIGJvb2tkb3duOjpodG1sX2RvY3VtZW50MjoKICAgIHRoZW1lOiBjb3NtbwogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgZ2l0aHViX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IGNvc21vCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKYmlibGlvZ3JhcGh5OiByZWZlcmVuY2VzLmJpYgotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyA9IFRSVUUsICAgICAgICAgIyBEaXNwbGF5IGNvZGUgY2h1bmtzCiAgZXZhbCA9IEZBTFNFLCAgICAgICAgIyBFdmFsdWF0ZSBjb2RlIGNodW5rcwogIHdhcm5pbmcgPSBGQUxTRSwgICAgICMgSGlkZSB3YXJuaW5ncwogIG1lc3NhZ2UgPSBGQUxTRSwgICAgICMgSGlkZSBtZXNzYWdlcwogIGNvbW1lbnQgPSAiIiAgICAgICAgICMgUHJldmVudHMgYXBwZW5kaW5nICcjIycgdG8gYmVnaW5uaW5nIG9mIGxpbmVzIGluIGNvZGUgb3V0cHV0CikKYGBgCgpUaGlzIG5vdGVib29rIHdpbGwgdXRpbGl6ZSBbZ2ZmcmVhZF0oaHR0cHM6Ly9jY2Iuamh1LmVkdS9zb2Z0d2FyZS9zdHJpbmd0aWUvZ2ZmLnNodG1sKSBbQHBlcnRlYTIwMjBdIHRvIGNyZWF0ZSBhbiBfQS5wdWxjaHJhc18gR1RGIGZpbGUgZnJvbSB0aGUgX0EucHVsY2hyYV8gZ2Vub21lIEdGRiwgd2hpY2ggaXMgbmVlZGVkIGZvciBkb3duc3RyZWFtIGFuYWx5c2lzIHdpdGggW0hJU0FUMl0oaHR0cHM6Ly9naXRodWIuY29tL0RhZWh3YW5LaW1MYWIvaGlzYXQyKTsgc3BlY2lmaWNhbGx5IGZvciBpZGVudGlmaWNhdGlvbiBvZiBleG9ucyBhbmQgc3BsaWNlIHNpdGVzLgoKIyBDcmVhdGUgYSBCYXNoIHZhcmlhYmxlcyBmaWxlCgpUaGlzIGFsbG93cyB1c2FnZSBvZiBCYXNoIHZhcmlhYmxlcyBhY3Jvc3MgUiBNYXJrZG93biBjaHVua3MuCgpgYGB7ciBzYXZlLWJhc2gtdmFyaWFibGVzLXRvLXJ2YXJzLWZpbGUsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KewplY2hvICIjIyMjIEFzc2lnbiBWYXJpYWJsZXMgIyMjIyIKZWNobyAiIgoKZWNobyAiIyBEYXRhIGRpcmVjdG9yaWVzIgplY2hvICdleHBvcnQgdGltZXNlcmllc19kaXI9L2hvbWUvc2hhcmVkLzhUQl9IRERfMDEvc2FtL2dpdHJlcG9zL3Vyb2wtZTUvdGltZXNlcmllc19tb2xlY3VsYXInCmVjaG8gJ2V4cG9ydCBnZW5vbWVfZGlyPSIke3RpbWVzZXJpZXNfZGlyfS9ELUFwdWwvZGF0YSInCmVjaG8gJ2V4cG9ydCBvdXRwdXRfZGlyX3RvcD0ke3RpbWVzZXJpZXNfZGlyfS9ELUFwdWwvb3V0cHV0LzAyLjAwLUQtQXB1bC1STkFzZXEtZ2ZmLXRvLWd0ZicKZWNobyAiIgoKZWNobyAiIyBJbnB1dC9vdXRwdXQgZmlsZXMiCgplY2hvICdleHBvcnQgZ2Vub21lX2dmZj0iJHtnZW5vbWVfZGlyfS9BcHVsY2hyYS1nZW5vbWUuZ2ZmIicKZWNobyAnZXhwb3J0IHRyYW5zY3JpcHRzX2d0Zj0iQXB1bGNocmEtZ2Vub21lLmd0ZiInCgplY2hvICIjIFBhdGhzIHRvIHByb2dyYW1zIgplY2hvICdleHBvcnQgcHJvZ3JhbXNfZGlyPSIvaG9tZS9zaGFyZWQiJwplY2hvICdleHBvcnQgZ2ZmcmVhZD0iJHtwcm9ncmFtc19kaXJ9L2dmZnJlYWQtMC4xMi43LkxpbnV4X3g4Nl82NC9nZmZyZWFkIicKCmVjaG8gIiMgU2V0IG51bWJlciBvZiBDUFVzIHRvIHVzZSIKZWNobyAnZXhwb3J0IHRocmVhZHM9NDAnCmVjaG8gIiIKCgplY2hvICIjIFByb2dyYW1zIGFzc29jaWF0aXZlIGFycmF5IgplY2hvICJkZWNsYXJlIC1BIHByb2dyYW1zX2FycmF5IgplY2hvICJwcm9ncmFtc19hcnJheT0oIgplY2hvICdbZ2ZmcmVhZF09IiR7Z2ZmcmVhZH0iIFwnCmVjaG8gIikiCmVjaG8gIiIKCmVjaG8gIiMgUHJpbnQgZm9ybWF0dGluZyIKZWNobyAnZXhwb3J0IGxpbmU9Ii0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIicKZWNobyAiIgp9ID4gLmJhc2h2YXJzCgpjYXQgLmJhc2h2YXJzCmBgYAoKIyBQcmV2aWV3IGFuZCBWYWxpZGF0ZSBHZW5vbWUgR0ZGCgojIyBJbnNwZWN0IEdGRgpgYGB7ciBwcmV2aWV3LWdlbm9tZS1nZmYsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCiMgTWFrZSBkaXJlY3RvcmllcywgaWYgdGhleSBkb24ndCBleGlzdApta2RpciAtLXBhcmVudHMgIiR7b3V0cHV0X2Rpcl90b3B9IgoKaGVhZCAtbiAyMCAiJHtnZW5vbWVfZ2ZmfSIKYGBgCgojIyBWYWxkaWF0ZSBHRkYKClRoaXMgaWRlbnRpZmllcyBpZiB0aGVyZSBhcmUgcm93cyB3aXRoID45IGZpZWxkcyAod2hpY2ggdGhlcmUgc2hvdWxkbid0IGJlIGluIGEgW0dGRjNdKGh0dHA6Ly9nbW9kLm9yZy93aWtpL0dGRjMpKS4KCkFkZGl0aW9uYWxseSwgaXQgcHJvdmlkZXMgYSBwcmV2aWV3IG9mIGFsbCByb3dzIGxlbmd0aHMgaWRlbnRpZmllZC4KCmBgYHtyIHZhbGlkYXRlLWdlbm9tZS1nZmYsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCiMgQ2FwdHVyZSBudW1iZXIgb2YgZmllbGRzIChORikgaW4gZWFjaCByb3cgaW4gYXJyYXkuCmZpZWxkX2NvdW50X2FycmF5PSgkKGF3ayAtRiAiXHQiICd7cHJpbnQgTkZ9JyAiJHtnZW5vbWVfZ2ZmfSIgfCBzb3J0IC0tdW5pcXVlKSkKCgojIENoZWNrIGFycmF5IGNvbnRlbnRzCmVjaG8gIkxpc3Qgb2YgbnVtYmVyIG9mIGZpZWxkcyBpbiAke2dlbm9tZV9nZmZ9OiIKZWNobyAiIgpmb3IgZmllbGRfY291bnQgaW4gIiR7ZmllbGRfY291bnRfYXJyYXlbQF19IgpkbwogIGVjaG8gIiR7ZmllbGRfY291bnR9Igpkb25lCgplY2hvICIiCmVjaG8gIiR7bGluZX0iCmVjaG8gIiIKCiMgUHJldmlldyBvZiBlYWNoIGxpbmUgInR5cGUiIHdpdGggYSBnaXZlbiBudW1iZXIgb2YgZmllbGRzCiMgQ2hlY2sgYXJyYXkgY29udGVudHMKZWNobyAiIgpmb3IgZmllbGRfY291bnQgaW4gIiR7ZmllbGRfY291bnRfYXJyYXlbQF19IgpkbwogIGVjaG8gIlByZXZpZXcgb2YgbGluZXMgd2l0aCAke2ZpZWxkX2NvdW50fSBmaWVsZChzKToiCiAgZWNobyAiIgogIGF3ayBcCiAgICAtdiBmaWVsZF9jb3VudD0iJHtmaWVsZF9jb3VudH0iIFwKICAgIC1GICJcdCIgXAogICAgJ05GID09IGZpZWxkX2NvdW50JyBcCiAgICAiJHtnZW5vbWVfZ2ZmfSIgXAogICAgfCBoZWFkCiAgZWNobyAiIgogIGVjaG8gIiR7bGluZX0iCiAgZWNobyAiIgpkb25lCmBgYApHcmVhdCEgVGhpcyBsb29rcyBsaWtlIGEgdmFsaWQgR0ZGLiBDYW4gcHJvY2VlZCB3aXRoIEdURiBnZW5lcmF0aW9uLgoKIyBHZW5lcmF0ZSBHVEYKCmBgYHtyIGdlbmVyYXRlLWdlbm9tZS1ndGYsIGVuZ2luZT0nYmFzaCcsIGV2YWw9RkFMU0V9CiMgTG9hZCBiYXNoIHZhcmlhYmxlcyBpbnRvIG1lbW9yeQpzb3VyY2UgLmJhc2h2YXJzCgoke3Byb2dyYW1zX2FycmF5W2dmZnJlYWRdfSAtRSBcCiIke2dlbm9tZV9nZmZ9IiAtVCBcCjE+ICR7b3V0cHV0X2Rpcl90b3B9LyIke3RyYW5zY3JpcHRzX2d0Zn0iIFwKMj4gJHtvdXRwdXRfZGlyX3RvcH0vZ2ZmcmVhZC1nZmZfdG9fZ3RmLnN0ZGVycgoKYGBgCgojIEluc3BlY3QgR1RGCgpgYGB7ciBpbnNwZWN0LWdlbm9tZS1ndGYsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCmhlYWQgJHtvdXRwdXRfZGlyX3RvcH0vIiR7dHJhbnNjcmlwdHNfZ3RmfSIKCmBgYAoKIyMgQ29weSBHVEYgdG8gYEQtQXB1bC9kYXRhYAoKVG8gaGVscCBtYWtlIHRoaXMgZWFzaWVyIHRvIGxvY2F0ZSwgd2lsbCBjb3B5IHRvIHRoZSBgRC1BcHVsL2RhdGFgIGRpcmVjdG9yeSwgd2hpY2ggYWxzbyBjb250YWlucwp0aGUgZ2Vub21lIEZhc3RBLCBnZW5vbWUgRmFzdEEgaW5kZXgsIGFuZCB0aGUgZ2Vub21lIEdGRiBmaWxlcy4KCmBgYHtyIGNvcHktZ2Vub21lLWd0ZiwgZW5naW5lPSdiYXNoJywgZXZhbD1GQUxTRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCmNwICR7b3V0cHV0X2Rpcl90b3B9LyIke3RyYW5zY3JpcHRzX2d0Zn0iICIke2dlbm9tZV9kaXJ9IgoKYGBg