code: def addparent(args):
      
      p = OptionParser(addparent.__doc__)
      p.add_option("--childfeat", default="CDS", help="Type of children feature")
      p.add_option("--parentfeat", default="mRNA", help="Type of merged feature")
      p.set_outfile()
      opts, args = p.parse_args(args)
  
      if len(args) != 1:
          sys.exit(not p.print_help())
  
      gff_file, = args
      gff = Gff(gff_file)
      data = defaultdict(list)
      for g in gff:
          if g.type != opts.childfeat:
              continue
          data[g.parent].append(g)
  
      logging.debug("A total of {0} {1} features clustered".\
                      format(len(data), opts.childfeat))
  
      parents = []
      for parent, dd in data.items():
          d = dd[0]
          start, end = min(x.start for x in dd), max(x.end for x in dd)
          gffline = "\t".join(str(x) for x in \
                          (d.seqid, d.source, opts.parentfeat, start, end,
                           ".", d.strand, ".", "ID={0};Name={0}".format(parent)))
          parents.append(GffLine(gffline))
      parents.sort(key=lambda x: (x.seqid, x.start))
      logging.debug("Merged feature sorted")
  
      fw = must_open(opts.outfile, "w")
      for parent in parents:
          print(parent, file=fw)
          parent_id = parent.id
          for d in data[parent_id]:
              if d.accn == parent_id:
                  new_id = "{0}.{1}1".format(parent_id, opts.childfeat)
                  d.set_attr("ID", new_id)
                  d.set_attr("Name", new_id, update=True)
              print(d, file=fw)
      fw.close()
docs: %prog addparent file.gff
  
      Merge sister features and infer parents.