Answers.Body: <p>The <a href="http://genometools.org/" rel="nofollow noreferrer">GenomeTools</a> package has lots of small applications that let you massage GFF3. It may have a converter, or it may let you tweak your existing GFF3 so that gffread works</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-14T13:49:09.250Z
Answers.Text: Oh... I should read past the first item on the list... Try using gt gff3 to transform and output GFF3 files?
Answers.UserDisplayName: Dan
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-14T13:53:55.940Z
Answers.Text: yes @Dan, I tried gt (Genome Tools package) - see point 2 of my question, and it is not working as it is.
Answers.UserDisplayName: aechchiki
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-14T14:12:58.193Z
Answers.Text: Please edit your question and include an example of how the OP can use your suggested tool to do what they ask. As it stands, this is more of a comment than an answer. Please also see https://meta.stackexchange.com/q/225370/203101
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-14T20:53:15.097Z
Answers.Text: @terdon Do you mean the answer?
Answers.UserDisplayName: Kamil S Jaron
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-17T00:37:06.027Z
Answers.Text: @KamilSJaron d'oh! Yes, sorry, I was asking Dan to edit this answer, not the question.
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-14T13:46:53.463Z
Answers.LastActivityDate: 2017-07-14T13:46:53.463Z
Answers.UserDisplayName: Dan
Answers.Body: <p>I'm quite sure it will work with <code>agat_convert_sp_gff2gtf.pl</code> from <a href="https://github.com/NBISweden/AGAT" rel="nofollow noreferrer">AGAT</a>.<br />
  See the review of the different solution I made here:
  <a href="https://agat.readthedocs.io/en/latest/gff_to_gtf.html" rel="nofollow noreferrer">https://agat.readthedocs.io/en/latest/gff_to_gtf.html</a></p>
  <p>AGAT it the only one you can decide wich version of GTF you require as output.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-07-09T10:13:02.447Z
Answers.LastActivityDate: 2021-07-09T10:13:02.447Z
Answers.UserDisplayName: juke34
Answers.Body: <p>The following bit of python code should work:</p>
  
  <pre class="lang-py prettyprint-override"><code>#!/usr/bin/env python
  import sys
  
  lastTranscript = [None, None, None, []]  # ID, chrom, strand, [(start, end, score), ...]
  
  
  def getID(s):
      """Parse out the ID attribute"""
      s = s.split(";")
      for k in s:
          if k.startswith("ID="):
              return k[3:]
      return None
  
  
  def dumpLastTranscript():
      """Print the last transcript"""
      bounds = sorted(lastTranscript[3])
      print("{}\tgmapidx\tgene\t{}\t{}\t.\t{}\t.\tgene_id \"{}\"; transcript_id \"{}\";".format(lastTranscript[1], bounds[0][0], bounds[-1][1], lastTranscript[2], lastTranscript[0], lastTranscript[0]))
      print("{}\tgmapidx\ttranscript\t{}\t{}\t.\t{}\t.\tgene_id \"{}\"; transcript_id \"{}\";".format(lastTranscript[1], bounds[0][0], bounds[-1][1], lastTranscript[2], lastTranscript[0], lastTranscript[0]))
      for start, end, score in bounds:
          print("{}\tgmapidx\texon\t{}\t{}\t{}\t{}\t.\tgene_id \"{}\"; transcript_id \"{}\";".format(lastTranscript[1], start, end, score, lastTranscript[2], lastTranscript[0], lastTranscript[0]))
  
  
  def handleLine(cols):
      """Handle a single line, appending the exon bounds to the previous if relevant"""
      ID = getID(cols[8])
      assert(ID is not None)
      if lastTranscript[0] is not None and lastTranscript[0] != ID:
          dumpLastTranscript()
          lastTranscript[3] = []
      lastTranscript[0] = ID
      lastTranscript[1] = cols[0]
      lastTranscript[2] = cols[6]
      lastTranscript[3].append((int(cols[3]), int(cols[4]), cols[5]))
  
  
  f = open(sys.argv[1])
  for line in f:
      if line.startswith("#"):
          continue
      cols = line.strip().split("\t")
      handleLine(cols)
  
  dumpLastTranscript()
  f.close()
  </code></pre>
  
  <p>If you saved that as <code>gff2gtf.py</code> and made it executable, the usage would be <code>./gff2gtf.py foo.gff3 &gt; foo.gtf</code>. With the example that you provided in your post, the result is:</p>
  
  <pre><code>2L  gmapidx gene    18442664    18443024    .   -   .   gene_id "ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d.path1"; transcript_id "ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d.path1";
  2L  gmapidx transcript  18442664    18443024    .   -   .   gene_id "ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d.path1"; transcript_id "ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d.path1";
  2L  gmapidx exon    18442664    18443024    79  -   .   gene_id "ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d.path1"; transcript_id "ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d.path1";
  3R  gmapidx gene    15853880    15855742    .   +   .   gene_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1"; transcript_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1";
  3R  gmapidx transcript  15853880    15855742    .   +   .   gene_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1"; transcript_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1";
  3R  gmapidx exon    15853880    15855465    96  +   .   gene_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1"; transcript_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1";
  3R  gmapidx exon    15855529    15855742    97  +   .   gene_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1"; transcript_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1";
  X   gmapidx gene    14837470    14838142    .   -   .   gene_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1"; transcript_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1";
  X   gmapidx transcript  14837470    14838142    .   -   .   gene_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1"; transcript_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1";
  X   gmapidx exon    14837470    14837753    92  -   .   gene_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1"; transcript_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1";
  X   gmapidx exon    14837810    14838142    93  -   .   gene_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1"; transcript_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1";
  </code></pre>
  
  <p>That at least looks like correct gtf 2.2 format to me.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-09-17T08:07:25.037Z
Answers.Text: Close to be GTF2.2 but is not. Feature type from 3rd column should be filtered to match the GTF2.2 specification. Only 9 feature types are accepted. `Gene` is not as example. It became accepted in version 2.5. See here https://agat.readthedocs.io/en/latest/gxf.html#gtf2-2
Answers.UserDisplayName: juke34
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-09-17T08:10:26.177Z
Answers.Text: @juke34 As there is no coherent GFF specification, you're always going to have to tweak something or other.
Answers.UserDisplayName: Devon Ryan
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-09-17T08:16:55.093Z
Answers.Text: There are clear specifications (I would say excepted for GFF0 and GTF1) but it is easy to not follow them ^^. Have you look at the review I made? I tried to gather all the information in one place:  https://agat.readthedocs.io/en/latest/gxf.html
Answers.UserDisplayName: juke34
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-15T11:30:13.013Z
Answers.LastActivityDate: 2017-07-17T07:29:29.317Z
Answers.LastEditDate: 2017-07-17T07:29:29.317Z
Answers.UserDisplayName: Devon Ryan
Body: <p>I would like to convert a file in <code>gff3</code> format to a <code>gtf2.2</code> format.</p>
  
  <p>The reason why I would like to do this is: I have a set of transcripts assembled by a bunch of different software (and using RNA-seq data from different sequencing technologies) and I would like to compare each of those sets with the reference transcriptome annotation for that species (<em>D. melanogaster</em>). I <a href="https://bioinformatics.stackexchange.com/questions/2036/tools-to-reconcile-experimental-transcripts-with-reference-annotation">already asked for the community advice</a> about how to proceed on that, but to run the suggested software (<a href="https://tacorna.github.io/" rel="noreferrer">TACO</a> and <a href="http://cole-trapnell-lab.github.io/cufflinks/cuffmerge/" rel="noreferrer">cuffmerge</a>) I need to have a GTF file containing the experimental transcripts to compare to the reference transcripts (GTF).</p>
  
  <p>Up to now, I <strong>unsuccessfully</strong> tried: </p>
  
  <ol>
  <li><code>gffread</code> utility in the <a href="http://cole-trapnell-lab.github.io/cufflinks/" rel="noreferrer">Cufflinks</a> package (<code>gffread input.gff3 -T -o output.gtf</code>): this results in an empty <code>output.gtf</code> file and an empty <code>log</code> file (used <code>Cufflinks</code> v.2.2.1) - I contacted the authors via their <a href="https://groups.google.com/d/msg/tuxedo-tools-users/T-qE4P67-HU/O_up6Yh6BgAJ" rel="noreferrer">Google group</a> but haven't heard of them yet </li>
  <li><code>gff3_to_gtf</code> utility in the <a href="http://genometools.org/" rel="noreferrer">GenomeTools</a> (<code>gt</code>) package (<code>gt gff3_to_gtf input.gff3 -o output.gtf</code>): the output is not created and the log file is not informative - I contacted the authors via their <a href="http://gt-users@genometools.org" rel="noreferrer">mailing list</a> but haven't heard of them yet </li>
  <li><code>GFF3_to_GTF</code> utility in the <a href="https://testtoolshed.g2.bx.psu.edu/repository/display_tool?repository_id=afcb6456d8e300ed&amp;tool_config=database%2Fcommunity_files%2F000%2Frepo_21%2Ffml_gff_converter_programs%2Fgalaxy%2Fgff3_to_gtf.xml&amp;changeset_revision=4c459744cab1" rel="noreferrer">FML</a> package (<code>./gff3_to_gtf_converter.pl input.gff3 output.gtf</code>): the output just contains a header (<code>##gff-version 2.5</code>) and the <code>log</code> is empty</li>
  </ol>
  
  <p>The <code>gff3</code> file was created as output of <a href="https://wiki.gacrc.uga.edu/wiki/Gmap" rel="noreferrer">GMAP</a>, and contains the transcripts as found by alignment to the reference (specifying option <code>-f gff3_match_cdna</code>). </p>
  
  <p>[Edit: what I found out a poteriori, is that this format is not a standard gff3, thus the conversion is not trivial...]</p>
  
  <p>Here is the beginning of the gff3 file I tried to convert: </p>
  
  <pre><code>$ head r9_gmap_match-cdna.gff
  ##gff-version   3
  # Generated by GMAP version 2017-04-24 using call:  /home/aechchik/software/gmap-2017-04-24/bin/gmap.sse42 -d gmapidx -D /scratch/beegfs/monthly/aechchik/isoforms/ref/chromosomes/ -f gff3_match_cdna -n 0 -t 20 r9_2d.fasta
  2L    gmapidx    cDNA_match    18442664    18443024    79    -    . ID=ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d.path1;Name=ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d;Target=ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d 141 489;Gap=M13 I10 M8 D3 M8 D3 M32 D1 M4 D2 M5 D3 M34 I3 M6 D1 M7 D1 M5 D1 M30 D2 M16 I1 M8 D3 M10 D1 M5 D1 M6 I1 M8 I1 M8 D1 M33 D3 M33 I1 M28 D3 M25
  ###
  3R    gmapidx    cDNA_match    15853880    15855465    96    +    . ID=dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1;Name=dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d;Target=dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d 80 1645;Gap=M46 D2 M12 D2 M157 D3 M4 D1 M50 I2 M3 I1 M12 I1 M68 I1 M66 I1 M53 D2 M47 D1 M16 D1 M35 D1 M155 D1 M28 D1 M166 D2 M47 D1 M8 D4 M69 D1 M28 D1 M5 D1 M12 D1 M202 I1 M115 D1 M61 I2 M7 D1 M7 I1 M36 D2 M41
  3R    gmapidx    cDNA_match    15855529    15855742    97    +    . ID=dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1;Name=dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d;Target=dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d 1646 1856;Gap=M21 D1 M68 D1 M85 D1 M37
  ###
  X    gmapidx    cDNA_match    14837810    14838142    93    -    . ID=960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1;Name=960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d;Target=960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d 74 406;Gap=M13 D1 M182 I1 M14 I2 M56 I1 M30 D2 M21 D1 M13
  X    gmapidx    cDNA_match    14837470    14837753    92    -    . ID=960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1;Name=960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d;Target=960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d 407 688;Gap=I2 M5 I1 M64 I1 M44 D1 M9 D5 M31 D3 M23 I1 M19 I1 M25 I1 M26 D1 M19 I1 M9
  ###
  </code></pre>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-07-14T14:43:13.973Z
Comments.Text: I can't get cufflinks to work with this either. Strange. Could you explain what you need, exactly? I mean, GTF is basically GFF2. Would it be OK to just remove the attributes? What information do you need to keep? Basically, what will you use the GTF for? Do you need the `gene_id` and `transcript_id` fields and, if so, where would that information come from? It might be helpful if you came into our [chat room](https://chat.stackexchange.com/rooms/58858/bioinformatics). If you do, ping me (`@terdon`) to let me know.
Comments.UserDisplayName: terdon
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-07-14T14:56:07.060Z
Comments.Text: I tried to convert this with `rtracklayer` in R and also failed (rtracklayer doesn't want to output proper GTF format) :( I wonder if a bit of python/perl would suffice.
Comments.UserDisplayName: Devon Ryan
Tags: <software-recommendation><format-conversion><gff3><gtf>
Title: How to convert GFF3 to GTF2
ThreadText: # How to convert GFF3 to GTF2
  
  (Asked by: username_0 on 2017-07-14)
  
  I would like to convert a file in `gff3` format to a `gtf2.2` format.
  
  The reason why I would like to do this is: I have a set of transcripts assembled by a bunch of different software (and using RNA-seq data from different sequencing technologies) and I would like to compare each of those sets with the reference transcriptome annotation for that species (*D. melanogaster*). I [already asked for the community advice](https://bioinformatics.stackexchange.com/questions/2036/tools-to-reconcile-experimental-transcripts-with-reference-annotation) about how to proceed on that, but to run the suggested software ([TACO](https://tacorna.github.io/) and [cuffmerge](http://cole-trapnell-lab.github.io/cufflinks/cuffmerge/)) I need to have a GTF file containing the experimental transcripts to compare to the reference transcripts (GTF).
  
  Up to now, I **unsuccessfully** tried:
  
  1. `gffread` utility in the [Cufflinks](http://cole-trapnell-lab.github.io/cufflinks/) package (`gffread input.gff3 -T -o output.gtf`): this results in an empty `output.gtf` file and an empty `log` file (used `Cufflinks` v.2.2.1) - I contacted the authors via their [Google group](https://groups.google.com/d/msg/tuxedo-tools-users/T-qE4P67-HU/O_up6Yh6BgAJ) but haven't heard of them yet
  2. `gff3_to_gtf` utility in the [GenomeTools](http://genometools.org/) (`gt`) package (`gt gff3_to_gtf input.gff3 -o output.gtf`): the output is not created and the log file is not informative - I contacted the authors via their [mailing list](http://gt-users@genometools.org) but haven't heard of them yet
  3. `GFF3_to_GTF` utility in the [FML](https://testtoolshed.g2.bx.psu.edu/repository/display_tool?repository_id=afcb6456d8e300ed&tool_config=database%2Fcommunity_files%2F000%2Frepo_21%2Ffml_gff_converter_programs%2Fgalaxy%2Fgff3_to_gtf.xml&changeset_revision=4c459744cab1) package (`./gff3_to_gtf_converter.pl input.gff3 output.gtf`): the output just contains a header (`##gff-version 2.5`) and the `log` is empty
  
  The `gff3` file was created as output of [GMAP](https://wiki.gacrc.uga.edu/wiki/Gmap), and contains the transcripts as found by alignment to the reference (specifying option `-f gff3_match_cdna`).
  
  [Edit: what I found out a poteriori, is that this format is not a standard gff3, thus the conversion is not trivial...]
  
  Here is the beginning of the gff3 file I tried to convert:
  
  ```
  $ head r9_gmap_match-cdna.gff
  ##gff-version   3
  # Generated by GMAP version 2017-04-24 using call:  /home/aechchik/software/gmap-2017-04-24/bin/gmap.sse42 -d gmapidx -D /scratch/beegfs/monthly/aechchik/isoforms/ref/chromosomes/ -f gff3_match_cdna -n 0 -t 20 r9_2d.fasta
  2L    gmapidx    cDNA_match    18442664    18443024    79    -    . ID=ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d.path1;Name=ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d;Target=ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d 141 489;Gap=M13 I10 M8 D3 M8 D3 M32 D1 M4 D2 M5 D3 M34 I3 M6 D1 M7 D1 M5 D1 M30 D2 M16 I1 M8 D3 M10 D1 M5 D1 M6 I1 M8 I1 M8 D1 M33 D3 M33 I1 M28 D3 M25
  ###
  3R    gmapidx    cDNA_match    15853880    15855465    96    +    . ID=dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1;Name=dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d;Target=dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d 80 1645;Gap=M46 D2 M12 D2 M157 D3 M4 D1 M50 I2 M3 I1 M12 I1 M68 I1 M66 I1 M53 D2 M47 D1 M16 D1 M35 D1 M155 D1 M28 D1 M166 D2 M47 D1 M8 D4 M69 D1 M28 D1 M5 D1 M12 D1 M202 I1 M115 D1 M61 I2 M7 D1 M7 I1 M36 D2 M41
  3R    gmapidx    cDNA_match    15855529    15855742    97    +    . ID=dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1;Name=dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d;Target=dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d 1646 1856;Gap=M21 D1 M68 D1 M85 D1 M37
  ###
  X    gmapidx    cDNA_match    14837810    14838142    93    -    . ID=960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1;Name=960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d;Target=960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d 74 406;Gap=M13 D1 M182 I1 M14 I2 M56 I1 M30 D2 M21 D1 M13
  X    gmapidx    cDNA_match    14837470    14837753    92    -    . ID=960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1;Name=960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d;Target=960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d 407 688;Gap=I2 M5 I1 M64 I1 M44 D1 M9 D5 M31 D3 M23 I1 M19 I1 M25 I1 M26 D1 M19 I1 M9
  ###
  
  ```
  
  **Tags:** software-recommendation, format-conversion, gff3, gtf
  
  > **Comments:**
  > **username_1**: I can't get cufflinks to work with this either. Strange. Could you explain what you need, exactly? I mean, GTF is basically GFF2. Would it be OK to just remove the attributes? What information do you need to keep? Basically, what will you use the GTF for? Do you need the `gene_id` and `transcript_id` fields and, if so, where would that information come from? It might be helpful if you came into our [chat room](https://chat.stackexchange.com/rooms/58858/bioinformatics). If you do, ping me (`@username_1`) to let me know.  
  > **username_2**: I tried to convert this with `rtracklayer` in R and also failed (rtracklayer doesn't want to output proper GTF format) :( I wonder if a bit of python/perl would suffice.  
  
  ---
  
  ## 3 answers
  
  ### Answer by username_2 on 2017-07-15. Score: 5 | Accepted answer
  
  The following bit of python code should work:
  
  ```py
  #!/usr/bin/env python
  import sys
  
  lastTranscript = [None, None, None, []]  # ID, chrom, strand, [(start, end, score), ...]
  
  def getID(s):
      """Parse out the ID attribute"""
      s = s.split(";")
      for k in s:
          if k.startswith("ID="):
              return k[3:]
      return None
  
  def dumpLastTranscript():
      """Print the last transcript"""
      bounds = sorted(lastTranscript[3])
      print("{}\tgmapidx\tgene\t{}\t{}\t.\t{}\t.\tgene_id \"{}\"; transcript_id \"{}\";".format(lastTranscript[1], bounds[0][0], bounds[-1][1], lastTranscript[2], lastTranscript[0], lastTranscript[0]))
      print("{}\tgmapidx\ttranscript\t{}\t{}\t.\t{}\t.\tgene_id \"{}\"; transcript_id \"{}\";".format(lastTranscript[1], bounds[0][0], bounds[-1][1], lastTranscript[2], lastTranscript[0], lastTranscript[0]))
      for start, end, score in bounds:
          print("{}\tgmapidx\texon\t{}\t{}\t{}\t{}\t.\tgene_id \"{}\"; transcript_id \"{}\";".format(lastTranscript[1], start, end, score, lastTranscript[2], lastTranscript[0], lastTranscript[0]))
  
  def handleLine(cols):
      """Handle a single line, appending the exon bounds to the previous if relevant"""
      ID = getID(cols[8])
      assert(ID is not None)
      if lastTranscript[0] is not None and lastTranscript[0] != ID:
          dumpLastTranscript()
          lastTranscript[3] = []
      lastTranscript[0] = ID
      lastTranscript[1] = cols[0]
      lastTranscript[2] = cols[6]
      lastTranscript[3].append((int(cols[3]), int(cols[4]), cols[5]))
  
  f = open(sys.argv[1])
  for line in f:
      if line.startswith("#"):
          continue
      cols = line.strip().split("\t")
      handleLine(cols)
  
  dumpLastTranscript()
  f.close()
  
  ```
  
  If you saved that as `gff2gtf.py` and made it executable, the usage would be `./gff2gtf.py foo.gff3 > foo.gtf`. With the example that you provided in your post, the result is:
  
  ```
  2L  gmapidx gene    18442664    18443024    .   -   .   gene_id "ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d.path1"; transcript_id "ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d.path1";
  2L  gmapidx transcript  18442664    18443024    .   -   .   gene_id "ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d.path1"; transcript_id "ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d.path1";
  2L  gmapidx exon    18442664    18443024    79  -   .   gene_id "ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d.path1"; transcript_id "ae6a7818-85b5-4739-8031-e58f4462ad41_Basecall_2D_2d.path1";
  3R  gmapidx gene    15853880    15855742    .   +   .   gene_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1"; transcript_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1";
  3R  gmapidx transcript  15853880    15855742    .   +   .   gene_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1"; transcript_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1";
  3R  gmapidx exon    15853880    15855465    96  +   .   gene_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1"; transcript_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1";
  3R  gmapidx exon    15855529    15855742    97  +   .   gene_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1"; transcript_id "dd2444cf-34d6-4cd3-87ab-0ae1f3cb1f96_Basecall_2D_2d.path1";
  X   gmapidx gene    14837470    14838142    .   -   .   gene_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1"; transcript_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1";
  X   gmapidx transcript  14837470    14838142    .   -   .   gene_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1"; transcript_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1";
  X   gmapidx exon    14837470    14837753    92  -   .   gene_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1"; transcript_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1";
  X   gmapidx exon    14837810    14838142    93  -   .   gene_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1"; transcript_id "960b50cd-945e-4c12-b9bc-367f965575bb_Basecall_2D_2d.path1";
  
  ```
  
  That at least looks like correct gtf 2.2 format to me.
  
  > **Comments:**
  > **username_5**: Close to be GTF2.2 but is not. Feature type from 3rd column should be filtered to match the GTF2.2 specification. Only 9 feature types are accepted. `Gene` is not as example. It became accepted in version 2.5. See here https://agat.readthedocs.io/en/latest/gxf.html#gtf2-2  
  > **username_2**: @username_5 As there is no coherent GFF specification, you're always going to have to tweak something or other.  
  > **username_5**: There are clear specifications (I would say excepted for GFF0 and GTF1) but it is easy to not follow them ^^. Have you look at the review I made? I tried to gather all the information in one place:  https://agat.readthedocs.io/en/latest/gxf.html  
  
  ---
  
  ### Answer by username_3 on 2017-07-14. Score: 1
  
  The [GenomeTools](http://genometools.org/) package has lots of small applications that let you massage GFF3. It may have a converter, or it may let you tweak your existing GFF3 so that gffread works
  
  > **Comments:**
  > **username_3**: Oh... I should read past the first item on the list... Try using gt gff3 to transform and output GFF3 files?  
  > **username_0**: yes @username_3, I tried gt (Genome Tools package) - see point 2 of my question, and it is not working as it is.  
  > **username_1**: Please edit your question and include an example of how the OP can use your suggested tool to do what they ask. As it stands, this is more of a comment than an answer. Please also see https://meta.stackexchange.com/q/225370/203101  
  > **username_4**: @username_1 Do you mean the answer?  
  > **username_1**: @username_4 d'oh! Yes, sorry, I was asking Dan to edit this answer, not the question.  
  
  ---
  
  ### Answer by username_5 on 2021-07-09. Score: 0
  
  I'm quite sure it will work with `agat_convert_sp_gff2gtf.pl` from [AGAT](https://github.com/NBISweden/AGAT).  
  See the review of the different solution I made here:
  <https://agat.readthedocs.io/en/latest/gff_to_gtf.html>
  
  AGAT it the only one you can decide wich version of GTF you require as output.
  
  
  ---
  
  