code: def liftover(args):
      
      p = OptionParser(liftover.__doc__)
      p.add_option("--newid", default=False, action="store_true",
                   help="Make new identifiers")
      opts, args = p.parse_args(args)
  
      if len(args) != 3:
          sys.exit(not p.print_help())
  
      oldvcf, chainfile, newvcf = args
      ul = UniqueLiftover(chainfile)
      num_excluded = 0
      fp = open(oldvcf)
      fw = open(newvcf, "w")
      for row in fp:
          row = row.strip()
          if row[0] == '#':
              if row.startswith("##source="):
                  row = "##source={0}".format(__file__)
              elif row.startswith("##reference="):
                  row = "##reference=hg38"
              elif row.startswith("##contig="):
                  continue
              print(row.strip(), file=fw)
              continue
  
          v = VcfLine(row)
          # GRCh37.p2 has the same MT sequence as hg38 (but hg19 is different)
          if v.seqid == "MT":
              v.seqid = "chrM"
              print(v, file=fw)
              continue
  
          try:
              new_chrom, new_pos = ul.liftover_cpra(CM[v.seqid], v.pos)
          except:
              num_excluded +=1
              continue
  
          if new_chrom != None and new_pos != None:
              v.seqid, v.pos = new_chrom, new_pos
              if opts.newid:
                  v.rsid = "{0}:{1}".format(new_chrom.replace("chr", ""), new_pos)
              print(v, file=fw)
          else:
              num_excluded +=1
  
      logging.debug("Excluded {0}".format(num_excluded))
docs: %prog liftover old.vcf hg19ToHg38.over.chain.gz new.vcf
  
      Lift over coordinates in vcf file.