Author: Michael R. Crusoe <michael.crusoe@gmail.com>
Description: 2to3
--- hisat2.orig/extract_exons.py
+++ hisat2/extract_exons.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2015, Daehwan Kim <infphilo@gmail.com>
@@ -19,7 +19,7 @@
 # along with HISAT 2.  If not, see <http://www.gnu.org/licenses/>.
 #
 
-from __future__ import print_function
+
 
 from sys import stderr, exit
 from collections import defaultdict as dd, Counter
@@ -65,7 +65,7 @@
             trans[transcript_id][2].append([left, right])
 
     # Sort exons and merge where separating introns are <=5 bps
-    for tran, [chrom, strand, exons] in trans.items():
+    for tran, [chrom, strand, exons] in list(trans.items()):
             exons.sort()
             tmp_exons = [exons[0]]
             for i in range(1, len(exons)):
@@ -77,7 +77,7 @@
 
     # Calculate and print the unique junctions
     tmp_exons = set()
-    for chrom, strand, texons in trans.values():
+    for chrom, strand, texons in list(trans.values()):
         for i in range(len(texons)):
             tmp_exons.add((chrom, texons[i][0], texons[i][1], strand))
     tmp_exons = sorted(tmp_exons)
--- hisat2.orig/extract_splice_sites.py
+++ hisat2/extract_splice_sites.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2015, Daehwan Kim <infphilo@gmail.com>
@@ -19,7 +19,7 @@
 # along with HISAT 2.  If not, see <http://www.gnu.org/licenses/>.
 #
 
-from __future__ import print_function
+
 
 from sys import stderr, exit
 from collections import defaultdict as dd, Counter
@@ -65,7 +65,7 @@
             trans[transcript_id][2].append([left, right])
 
     # Sort exons and merge where separating introns are <=5 bps
-    for tran, [chrom, strand, exons] in trans.items():
+    for tran, [chrom, strand, exons] in list(trans.items()):
             exons.sort()
             tmp_exons = [exons[0]]
             for i in range(1, len(exons)):
@@ -77,7 +77,7 @@
 
     # Calculate and print the unique junctions
     junctions = set()
-    for chrom, strand, exons in trans.values():
+    for chrom, strand, exons in list(trans.values()):
         for i in range(1, len(exons)):
             junctions.add((chrom, exons[i-1][1], exons[i][0], strand))
     junctions = sorted(junctions)
@@ -89,7 +89,7 @@
     if verbose:
         exon_lengths, intron_lengths, trans_lengths = \
             Counter(), Counter(), Counter()
-        for chrom, strand, exons in trans.values():
+        for chrom, strand, exons in list(trans.values()):
             tran_len = 0
             for i, exon in enumerate(exons):
                 exon_len = exon[1]-exon[0]+1
@@ -101,7 +101,7 @@
             trans_lengths[tran_len] += 1
 
         print('genes: {}, genes with multiple isoforms: {}'.format(
-                len(genes), sum(len(v) > 1 for v in genes.values())),
+                len(genes), sum(len(v) > 1 for v in list(genes.values()))),
               file=stderr)
         print('transcripts: {}, transcript avg. length: {:d}'.format(
                 len(trans), sum(trans_lengths.elements())/len(trans)),
--- hisat2.orig/hisat2_extract_exons.py
+++ hisat2/hisat2_extract_exons.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2015, Daehwan Kim <infphilo@gmail.com>
@@ -19,7 +19,7 @@
 # along with HISAT 2.  If not, see <http://www.gnu.org/licenses/>.
 #
 
-from __future__ import print_function
+
 
 from sys import stderr, exit
 from collections import defaultdict as dd, Counter
@@ -65,7 +65,7 @@
             trans[transcript_id][2].append([left, right])
 
     # Sort exons and merge where separating introns are <=5 bps
-    for tran, [chrom, strand, exons] in trans.items():
+    for tran, [chrom, strand, exons] in list(trans.items()):
             exons.sort()
             tmp_exons = [exons[0]]
             for i in range(1, len(exons)):
@@ -77,7 +77,7 @@
 
     # Calculate and print the unique junctions
     tmp_exons = set()
-    for chrom, strand, texons in trans.values():
+    for chrom, strand, texons in list(trans.values()):
         for i in range(len(texons)):
             tmp_exons.add((chrom, texons[i][0], texons[i][1], strand))
     tmp_exons = sorted(tmp_exons)
--- hisat2.orig/hisat2_extract_snps_haplotypes_UCSC.py
+++ hisat2/hisat2_extract_snps_haplotypes_UCSC.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2015, Daehwan Kim <infphilo@gmail.com>
@@ -80,8 +80,8 @@
 
     # daehwan - for debugging purposes
     if a_chr != b_chr:
-        print a
-        print b
+        print(a)
+        print(b)
     
     assert a_chr == b_chr
     if a_pos != b_pos:
@@ -154,7 +154,7 @@
             vars_count[id] = 0
         vars_count[id] += 1
     vars_duplicate = set()
-    for id, count in vars_count.items():
+    for id, count in list(vars_count.items()):
         if count <= 1:
             continue
         vars_duplicate.add(id)
@@ -223,8 +223,8 @@
         else:
             assert type == 'I'
             type = "insertion"
-        print >> snp_file, "%s\t%s\t%s\t%s\t%s" % \
-            (varID, type, chr, pos, data)
+        print("%s\t%s\t%s\t%s\t%s" % \
+            (varID, type, chr, pos, data), file=snp_file)
 
     # genotypes_list looks like
     #    Var0: 0
@@ -301,7 +301,7 @@
             h_end += (int(h2_data) - 1)
         assert h_begin <= h_end
         h_new_begin = h_begin
-        for h_j in reversed(range(0, h_i)):
+        for h_j in reversed(list(range(0, h_i))):
             hc = haplotypes[h_j].split('#')
             _, hc_begin, hc_type, hc_data, _ = vars[int(hc[-1])]
             hc_begin = int(hc_begin)
@@ -317,8 +317,8 @@
         for id in h:
             var_dic = vars[int(id)][4]
             h_add.append(var_dic["id2"])
-        print >> haplotype_file, "ht%d\t%s\t%d\t%d\t%s" % \
-            (num_haplotypes, chr, h_new_begin, h_end, ','.join(h_add))
+        print("ht%d\t%s\t%d\t%d\t%s" % \
+            (num_haplotypes, chr, h_new_begin, h_end, ','.join(h_add)), file=haplotype_file)
         num_haplotypes += 1
 
     return num_haplotypes
@@ -447,10 +447,10 @@
                 if testset:
                     ref_seq = chr_seq[start-50:start+50]
                     alt_seq = chr_seq[start-50:start] + allele + chr_seq[start+1:start+50]
-                    print >> ref_testset_file, ">%s_single_%d" % (rs_id, start - 50)
-                    print >> ref_testset_file, ref_seq
-                    print >> alt_testset_file, ">%s_single_%d_%s" % (rs_id, start - 50, ref_seq)
-                    print >> alt_testset_file, alt_seq
+                    print(">%s_single_%d" % (rs_id, start - 50), file=ref_testset_file)
+                    print(ref_seq, file=ref_testset_file)
+                    print(">%s_single_%d_%s" % (rs_id, start - 50, ref_seq), file=alt_testset_file)
+                    print(alt_seq, file=alt_testset_file)
                 
         elif classType == "deletion":
             if start > 0:
@@ -474,10 +474,10 @@
             if testset and delLen > 0 and delLen <= 10:
                 ref_seq = chr_seq[start-50:start+50]
                 alt_seq = chr_seq[start-50:start] + chr_seq[start+delLen:start+50+delLen]
-                print >> ref_testset_file, ">%s_deletion_%d" % (rs_id, start - 50)
-                print >> ref_testset_file, ref_seq
-                print >> alt_testset_file, ">%s_deletion_%d_%s" % (rs_id, start - 50, ref_seq)
-                print >> alt_testset_file, alt_seq
+                print(">%s_deletion_%d" % (rs_id, start - 50), file=ref_testset_file)
+                print(ref_seq, file=ref_testset_file)
+                print(">%s_deletion_%d_%s" % (rs_id, start - 50, ref_seq), file=alt_testset_file)
+                print(alt_seq, file=alt_testset_file)
         else:
             assert classType == "insertion"
             if start > 0:
@@ -496,10 +496,10 @@
                     if testset and insLen > 0 and insLen <= 10:
                         ref_seq = chr_seq[start-50:start+50]
                         alt_seq = chr_seq[start-50:start] + allele + chr_seq[start:start+50-insLen]
-                        print >> ref_testset_file, ">%s_insertion_%d" % (rs_id, start - 50)
-                        print >> ref_testset_file, ref_seq
-                        print >> alt_testset_file, ">%s_insertion_%d_%s" % (rs_id, start - 50, ref_seq)
-                        print >> alt_testset_file, alt_seq
+                        print(">%s_insertion_%d" % (rs_id, start - 50), file=ref_testset_file)
+                        print(ref_seq, file=ref_testset_file)
+                        print(">%s_insertion_%d_%s" % (rs_id, start - 50, ref_seq), file=alt_testset_file)
+                        print(alt_seq, file=alt_testset_file)
 
         if curr_right < end:
             curr_right = end
--- hisat2.orig/hisat2_extract_snps_haplotypes_VCF.py
+++ hisat2/hisat2_extract_snps_haplotypes_VCF.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2016, Daehwan Kim <infphilo@gmail.com>
@@ -182,8 +182,8 @@
         else:
             assert type == 'I'
             type = "insertion"
-        print >> snp_file, "%s\t%s\t%s\t%s\t%s" % \
-            (varID, type, chr, pos, data)
+        print("%s\t%s\t%s\t%s\t%s" % \
+            (varID, type, chr, pos, data), file=snp_file)
 
     # variant compatibility
     vars_cmpt = [-1 for i in range(len(vars))]
@@ -387,7 +387,7 @@
             h_end += (int(h2_data) - 1)
         assert h_begin <= h_end
         h_new_begin = h_begin
-        for h_j in reversed(range(0, h_i)):
+        for h_j in reversed(list(range(0, h_i))):
             hc = haplotypes[h_j].split('#')
             _, hc_begin, hc_type, hc_data, _ = vars[int(hc[-1])]
             hc_begin = int(hc_begin)
@@ -403,8 +403,8 @@
         for id in h:
             var_dic = vars[int(id)][4]
             h_add.append(var_dic["id2"])
-        print >> haplotype_file, "ht%d\t%s\t%d\t%d\t%s" % \
-            (num_haplotypes, chr, h_new_begin, h_end, ','.join(h_add))
+        print("ht%d\t%s\t%d\t%d\t%s" % \
+            (num_haplotypes, chr, h_new_begin, h_end, ','.join(h_add)), file=haplotype_file)
         num_haplotypes += 1
 
     return num_haplotypes
@@ -504,26 +504,26 @@
                     
                 var_set.add(var_str)
 
-        print >> sys.stderr, "Number of variants in %s is:" % (genotype_vcf)
-        for chr, vars in genotype_var_list.items():
+        print("Number of variants in %s is:" % (genotype_vcf), file=sys.stderr)
+        for chr, vars in list(genotype_var_list.items()):
             vars = sorted(vars, cmp=compare_vars)
-            print >> sys.stderr, "\tChromosome %s: %d variants" % (chr, len(vars))
+            print("\tChromosome %s: %d variants" % (chr, len(vars)), file=sys.stderr)
 
-        for chr, gene_ranges in genotype_ranges.items():
-            for gene, value in gene_ranges.items():
+        for chr, gene_ranges in list(genotype_ranges.items()):
+            for gene, value in list(gene_ranges.items()):
                 gene_ranges[gene] = [value[0] - 100, value[1] + 100]
                 value = genotype_ranges[chr][gene]
                 if verbose:
-                    print >> sys.stderr, "%s\t%s\t%d-%d" % (chr, gene, value[0], value[1])
+                    print("%s\t%s\t%d-%d" % (chr, gene, value[0], value[1]), file=sys.stderr)
 
         if extra_files or True:
             clnsig_file = open("%s.clnsig" % base_fname, 'w')
-            for chr, vars in genotype_var_list.items():
+            for chr, vars in list(genotype_var_list.items()):
                 for var in vars:
                     varID = var[4]["id2"]
                     CLNSIG = var[4]["CLNSIG"]
                     gene = var[4]["gene"]
-                    print >> clnsig_file, "%s\t%s\t%s" % (varID, gene, CLNSIG)
+                    print("%s\t%s\t%s" % (varID, gene, CLNSIG), file=clnsig_file)
             clnsig_file.close()
 
     SNP_file = open("%s.snp" % base_fname, 'w')
@@ -532,28 +532,28 @@
     # Write reference information and backbone sequences into files
     if extra_files:
         ref_file = open("%s.ref" % base_fname, 'w')
-        for chr, gene_ranges in genotype_ranges.items():
-            for gene, value in gene_ranges.items():
+        for chr, gene_ranges in list(genotype_ranges.items()):
+            for gene, value in list(gene_ranges.items()):
                 left, right = value
                 if reference_type == "gene":
                     left, right = 0, right - left
-                print >> ref_file, "%s\t%s\t%d\t%d" % (gene, chr, left, right)
+                print("%s\t%s\t%d\t%d" % (gene, chr, left, right), file=ref_file)
         ref_file.close()
 
         if reference_type == "gene":
             backbone_file = open("%s_backbone.fa" % base_fname, 'w')
-            for chr, gene_ranges in genotype_ranges.items():
-                for gene, value in gene_ranges.items():
+            for chr, gene_ranges in list(genotype_ranges.items()):
+                for gene, value in list(gene_ranges.items()):
                     left, right = value
                     left, right = 0, right - left
-                    print >> backbone_file, ">%s" % (gene)
+                    print(">%s" % (gene), file=backbone_file)
                     backbone_seq = chr_dic[chr][value[0]:value[1]+1]
                     for s in range(0, len(backbone_seq), 60):
-                        print >> backbone_file, backbone_seq[s:s+60]
+                        print(backbone_seq[s:s+60], file=backbone_file)
             backbone_file.close()
         elif reference_type == "chromosome":
             first = True
-            for chr in genotype_ranges.keys():
+            for chr in list(genotype_ranges.keys()):
                 if first:
                     os.system("samtools faidx genome.fa %s > %s_backbone.fa" % (chr, base_fname))
                     first = False
@@ -638,11 +638,11 @@
                 offset = 0
                 gene = None
                 if num_lines % 10000 == 1:
-                    print >> sys.stderr, "\t%s:%d\r" % (chr, pos),
+                    print("\t%s:%d\r" % (chr, pos), end=' ', file=sys.stderr)
 
                 if chr_genotype_ranges:
                     skip = True
-                    for gene_, range_ in chr_genotype_ranges.items():
+                    for gene_, range_ in list(chr_genotype_ranges.items()):
                         if pos > range_[0] and pos < range_[1]:
                             skip = False
                             break
@@ -746,7 +746,7 @@
                 vars = []
 
         else:            
-            for chr in genotype_var_list.keys():
+            for chr in list(genotype_var_list.keys()):
                 chr_seq = chr_dic[chr]
                 chr_genotype_vars = genotype_var_list[chr]
                 curr_right = -1
@@ -873,7 +873,7 @@
             args.genotype_gene_list = args.genotype_gene_list.split(',')
 
         if len(args.genotype_gene_list) == 0:
-            print >> sys.stderr, "Error: please specify --genotype-gene-list."
+            print("Error: please specify --genotype-gene-list.", file=sys.stderr)
             sys.exit(1)
 
     else:
--- hisat2.orig/hisat2_extract_splice_sites.py
+++ hisat2/hisat2_extract_splice_sites.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2015, Daehwan Kim <infphilo@gmail.com>
@@ -19,7 +19,7 @@
 # along with HISAT 2.  If not, see <http://www.gnu.org/licenses/>.
 #
 
-from __future__ import print_function
+
 
 from sys import stderr, exit
 from collections import defaultdict as dd, Counter
@@ -65,7 +65,7 @@
             trans[transcript_id][2].append([left, right])
 
     # Sort exons and merge where separating introns are <=5 bps
-    for tran, [chrom, strand, exons] in trans.items():
+    for tran, [chrom, strand, exons] in list(trans.items()):
             exons.sort()
             tmp_exons = [exons[0]]
             for i in range(1, len(exons)):
@@ -77,7 +77,7 @@
 
     # Calculate and print the unique junctions
     junctions = set()
-    for chrom, strand, exons in trans.values():
+    for chrom, strand, exons in list(trans.values()):
         for i in range(1, len(exons)):
             junctions.add((chrom, exons[i-1][1], exons[i][0], strand))
     junctions = sorted(junctions)
@@ -89,7 +89,7 @@
     if verbose:
         exon_lengths, intron_lengths, trans_lengths = \
             Counter(), Counter(), Counter()
-        for chrom, strand, exons in trans.values():
+        for chrom, strand, exons in list(trans.values()):
             tran_len = 0
             for i, exon in enumerate(exons):
                 exon_len = exon[1]-exon[0]+1
@@ -101,7 +101,7 @@
             trans_lengths[tran_len] += 1
 
         print('genes: {}, genes with multiple isoforms: {}'.format(
-                len(genes), sum(len(v) > 1 for v in genes.values())),
+                len(genes), sum(len(v) > 1 for v in list(genes.values()))),
               file=stderr)
         print('transcripts: {}, transcript avg. length: {:d}'.format(
                 len(trans), sum(trans_lengths.elements())/len(trans)),
--- hisat2.orig/hisat2_simulate_reads.py
+++ hisat2/hisat2_simulate_reads.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2015, Daehwan Kim <infphilo@gmail.com>
@@ -137,7 +137,7 @@
             transcripts[transcript_id][2].append([left, right])
 
     # Sort exons and merge where separating introns are <=5 bps
-    for tran, [chr, strand, exons] in transcripts.items():
+    for tran, [chr, strand, exons] in list(transcripts.items()):
             exons.sort()
             tmp_exons = [exons[0]]
             for i in range(1, len(exons)):
@@ -148,7 +148,7 @@
             transcripts[tran] = [chr, strand, tmp_exons]
 
     tmp_transcripts = {}
-    for tran, [chr, strand, exons] in transcripts.items():
+    for tran, [chr, strand, exons] in list(transcripts.items()):
         exon_lens = [e[1] - e[0] + 1 for e in exons]
         transcript_len = sum(exon_lens)
         if transcript_len >= frag_len:
@@ -184,7 +184,7 @@
 """
 def sanity_check_input(genome_seq, genes, transcripts, snps, frag_len):
     num_canon_ss, num_ss = 0, 0
-    for transcript, [chr, strand, transcript_len, exons] in transcripts.items():
+    for transcript, [chr, strand, transcript_len, exons] in list(transcripts.items()):
         assert transcript_len >= frag_len
         if len(exons) <= 1:
             continue
@@ -206,10 +206,10 @@
             num_ss += 1
 
     if num_ss > 0:
-        print >> sys.stderr, "GT/AG splice sites: {}/{} ({:.2%})".format(num_canon_ss, num_ss, (float(num_canon_ss) / num_ss))
+        print("GT/AG splice sites: {}/{} ({:.2%})".format(num_canon_ss, num_ss, (float(num_canon_ss) / num_ss)), file=sys.stderr)
 
     num_alt_single, num_single = 0, 0
-    for chr, chr_snps in snps.items():
+    for chr, chr_snps in list(snps.items()):
         if chr not in genome_seq:
             continue
         chr_seq = genome_seq[chr]
@@ -227,7 +227,7 @@
             num_single += 1
 
     if num_single > 0:
-        print >> sys.stderr, "Alternative bases: {}/{} ({:.2%})".format(num_alt_single, num_single, (float(num_alt_single) / num_single))
+        print("Alternative bases: {}/{} ({:.2%})".format(num_alt_single, num_single, (float(num_alt_single) / num_single)), file=sys.stderr)
 
 
 """
@@ -259,7 +259,7 @@
 """
 def generate_dna_expr_profile(genome_seq):
     expr_profile = []
-    for chr_id, chr_seq in genome_seq.items():
+    for chr_id, chr_seq in list(genome_seq.items()):
         expr_profile.append(len(chr_seq))
     expr_sum = float(sum(expr_profile))
     expr_profile = [expr_profile[i] / expr_sum for i in range(len(expr_profile))]
@@ -523,8 +523,8 @@
         MD += ("{}".format(MD_match_len))
 
     if len(read_seq) != read_len:
-        print >> sys.stderr, "read length differs:", len(read_seq), "vs.", read_len
-        print >> sys.stderr, pos, "".join(cigars), cigar_descs, MD, XM, NM, Zs
+        print("read length differs:", len(read_seq), "vs.", read_len, file=sys.stderr)
+        print(pos, "".join(cigars), cigar_descs, MD, XM, NM, Zs, file=sys.stderr)
         assert False
 
     return pos, cigars, cigar_descs, MD, XM, NM, Zs, read_seq
@@ -654,8 +654,8 @@
         tMD += ("{}".format(match_len))
 
     if tMD != MD or tXM != XM or tNM != NM or XM > max_mismatch or XM != NM:
-        print >> sys.stderr, chr, pos, cigar, MD, XM, NM, Zs
-        print >> sys.stderr, tMD, tXM, tNM
+        print(chr, pos, cigar, MD, XM, NM, Zs, file=sys.stderr)
+        print(tMD, tXM, tNM, file=sys.stderr)
         assert False
         
         
@@ -695,18 +695,18 @@
     assert num_frag == sum(expr_profile)
 
     if rna:
-        transcript_ids = transcripts.keys()
+        transcript_ids = list(transcripts.keys())
         random.shuffle(transcript_ids)
         assert len(transcript_ids) >= len(expr_profile)
     else:
-        chr_ids = genome_seq.keys()
+        chr_ids = list(genome_seq.keys())
 
     sam_file = open(base_fname + ".sam", "w")
 
     # Write SAM header
-    print >> sam_file, "@HD\tVN:1.0\tSO:unsorted"
-    for chr in genome_seq.keys():
-        print >> sam_file, "@SQ\tSN:%s\tLN:%d" % (chr, len(genome_seq[chr]))
+    print("@HD\tVN:1.0\tSO:unsorted", file=sam_file)
+    for chr in list(genome_seq.keys()):
+        print("@SQ\tSN:%s\tLN:%d" % (chr, len(genome_seq[chr])), file=sam_file)
     
     read_file = open(base_fname + "_1.fa", "w")
     if paired_end:
@@ -721,10 +721,10 @@
             # daehwan - for debugging purposes
             # if transcript_id != "ENST00000398359":
             #    continue
-            print >> sys.stderr, transcript_id, t_num_frags
+            print(transcript_id, t_num_frags, file=sys.stderr)
         else:
             chr = chr_ids[t]
-            print >> sys.stderr, chr, t_num_frags
+            print(chr, t_num_frags, file=sys.stderr)
 
         assert chr in genome_seq
         chr_seq = genome_seq[chr]
@@ -789,19 +789,19 @@
             else:
                 XS, TI = "", ""                
 
-            print >> read_file, ">{}".format(cur_read_id)
+            print(">{}".format(cur_read_id), file=read_file)
             if swapped:
-                print >> read_file, reverse_complement(read_seq)
+                print(reverse_complement(read_seq), file=read_file)
             else:
-                print >> read_file, read_seq
-            print >> sam_file, "{}\t{}\t{}\t{}\t255\t{}\t{}\t{}\t0\t{}\t*\tXM:i:{}\tNM:i:{}\tMD:Z:{}{}{}{}".format(cur_read_id, flag, chr, pos + 1, cigar_str, chr, pos2 + 1, read_seq, XM, NM, MD, Zs, XS, TI)
+                print(read_seq, file=read_file)
+            print("{}\t{}\t{}\t{}\t255\t{}\t{}\t{}\t0\t{}\t*\tXM:i:{}\tNM:i:{}\tMD:Z:{}{}{}{}".format(cur_read_id, flag, chr, pos + 1, cigar_str, chr, pos2 + 1, read_seq, XM, NM, MD, Zs, XS, TI), file=sam_file)
             if paired_end:
-                print >> read2_file, ">{}".format(cur_read_id)
+                print(">{}".format(cur_read_id), file=read2_file)
                 if swapped:
-                    print >> read2_file, read2_seq
+                    print(read2_seq, file=read2_file)
                 else:
-                    print >> read2_file, reverse_complement(read2_seq)
-                print >> sam_file, "{}\t{}\t{}\t{}\t255\t{}\t{}\t{}\t0\t{}\t*\tXM:i:{}\tNM:i:{}\tMD:Z:{}{}{}{}".format(cur_read_id, flag2, chr, pos2 + 1, cigar2_str, chr, pos + 1, read2_seq, XM2, NM2, MD2, Zs2, XS, TI)
+                    print(reverse_complement(read2_seq), file=read2_file)
+                print("{}\t{}\t{}\t{}\t255\t{}\t{}\t{}\t0\t{}\t*\tXM:i:{}\tNM:i:{}\tMD:Z:{}{}{}{}".format(cur_read_id, flag2, chr, pos2 + 1, cigar2_str, chr, pos + 1, read2_seq, XM2, NM2, MD2, Zs2, XS, TI), file=sam_file)
 
             cur_read_id += 1
             
--- hisat2.orig/hisatgenotype.py
+++ hisat2/hisatgenotype.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2017, Daehwan Kim <infphilo@gmail.com>
@@ -56,9 +56,9 @@
 
     out_base_fname = read_fnames[0].split('/')[-1].split('.')[0]
 
-    print >> sys.stderr, "%s Aligning %s to %s ..." % (str(datetime.now()), ' '.join(read_fnames), base_fname)
+    print("%s Aligning %s to %s ..." % (str(datetime.now()), ' '.join(read_fnames), base_fname), file=sys.stderr)
     if verbose:
-        print >> sys.stderr, "\t%s" % (' '.join(aligner_cmd))
+        print("\t%s" % (' '.join(aligner_cmd)), file=sys.stderr)
 
     align_proc = subprocess.Popen(aligner_cmd,
                                   stdout=subprocess.PIPE,
@@ -77,7 +77,7 @@
     # Increase the maximum number of files that can be opened
     resource.setrlimit(resource.RLIMIT_NOFILE, (10000, 10240))
     
-    print >> sys.stderr, "%s Sorting %s ..." % (str(datetime.now()), unsorted_bam_fname)
+    print("%s Sorting %s ..." % (str(datetime.now()), unsorted_bam_fname), file=sys.stderr)
     bam_fname = "%s.bam" % out_base_fname
     bamsort_cmd = ["samtools",
                    "sort",
@@ -86,7 +86,7 @@
                    unsorted_bam_fname,
                    "-o", bam_fname]    
     if verbose:
-        print >> sys.stderr, "\t%s" % ' '.join(bamsort_cmd)
+        print("\t%s" % ' '.join(bamsort_cmd), file=sys.stderr)
     bamsort_proc = subprocess.call(bamsort_cmd)
     os.remove(unsorted_bam_fname)
 
@@ -100,12 +100,12 @@
 """
 def index_bam(bam_fname,
               verbose):
-    print >> sys.stderr, "%s Indexing %s ..." % (str(datetime.now()), bam_fname)
+    print("%s Indexing %s ..." % (str(datetime.now()), bam_fname), file=sys.stderr)
     bamindex_cmd = ["samtools",
                     "index",
                     bam_fname]
     if verbose:
-        print >> sys.stderr, "\t%s" % ' '.join(bamindex_cmd)
+        print("\t%s" % ' '.join(bamindex_cmd), file=sys.stderr)
     bamindex_proc = subprocess.call(bamindex_cmd)
 
 
@@ -158,7 +158,7 @@
 
     bamview_cmd = ["samtools", "view", bam_fname, "%s:%d-%d" % (chr, left+1, right+1)]
     if verbose:
-        print >> sys.stderr, "\t%s" % ' '.join(bamview_cmd)
+        print("\t%s" % ' '.join(bamview_cmd), file=sys.stderr)
     bamview_proc = subprocess.Popen(bamview_cmd,
                                     stdout=subprocess.PIPE,
                                     stderr=open("/dev/null", 'w'))
@@ -265,7 +265,7 @@
         genotype_cmd += ["--assembly"]
 
     if verbose:
-        print >> sys.stderr, "\t%s" % ' '.join(genotype_cmd)
+        print("\t%s" % ' '.join(genotype_cmd), file=sys.stderr)
     genotype_proc = subprocess.Popen(genotype_cmd)
     genotype_proc.communicate()
         
@@ -295,9 +295,9 @@
     # hisat2 graph index files
     genotype_fnames += ["%s.%d.ht2" % (base_fname, i+1) for i in range(8)]
     if not typing_common.check_files(genotype_fnames):
-        print >> sys.stderr, "Error: some of the following files are missing!"
+        print("Error: some of the following files are missing!", file=sys.stderr)
         for fname in genotype_fnames:
-            print >> sys.stderr, "\t%s" % fname
+            print("\t%s" % fname, file=sys.stderr)
         sys.exit(1)
 
     # Read region alleles (names and sequences)
@@ -321,7 +321,7 @@
         region_loci[family].append([locus_name, allele_name, chr, left, right])
 
     if len(region_loci) <= 0:
-        print >> sys.stderr, "Warning: no region exists!"
+        print("Warning: no region exists!", file=sys.stderr)
         sys.exit(1)
 
     # Align reads, and sort the alignments into a BAM file
@@ -338,13 +338,13 @@
     assert os.path.exists(alignment_fname + ".bai")
 
     # Extract reads and perform genotyping
-    for family, loci in region_loci.items():
-        print >> sys.stderr, "Analyzing %s ..." % family.upper()
+    for family, loci in list(region_loci.items()):
+        print("Analyzing %s ..." % family.upper(), file=sys.stderr)
         for locus_name, allele_name, chr, left, right in loci:
             out_read_fname = "%s.%s" % (family, locus_name)
             if verbose:
-                print >> sys.stderr, "\tExtracting reads beloning to %s-%s ..." % \
-                    (family, locus_name)
+                print("\tExtracting reads beloning to %s-%s ..." % \
+                    (family, locus_name), file=sys.stderr)
 
             extracted_read_fnames = extract_reads(alignment_fname,
                                                   chr,
@@ -365,7 +365,7 @@
                                local_database,
                                threads,
                                verbose)
-        print >> sys.stderr
+        print(file=sys.stderr)
 
     
                 
@@ -442,7 +442,7 @@
         for region in args.region_list.split(','):
             region = region.split('.')
             if len(region) < 1 or len(region) > 2:
-                print >> sys.stderr, "Error: --region-list is incorrectly formatted."
+                print("Error: --region-list is incorrectly formatted.", file=sys.stderr)
                 sys.exit(1)
                 
             family = region[0].lower()
@@ -456,12 +456,12 @@
     read_fnames = []
     if args.alignment_fname != "":
         if not os.path.exists(args.alignment_fname):
-            print >> sys.stderr, "Error: %s does not exist." % args.alignment_fname
+            print("Error: %s does not exist." % args.alignment_fname, file=sys.stderr)
     elif args.read_fname_U != "":
         read_fnames = [args.read_fname_U]
     else:
         if args.read_fname_1 == "" or args.read_fname_2 == "":
-            print >> sys.stderr, "Error: please specify read file names correctly: -U or -1 and -2"
+            print("Error: please specify read file names correctly: -U or -1 and -2", file=sys.stderr)
             sys.exit(1)
         read_fnames = [args.read_fname_1, args.read_fname_2]
 
--- hisat2.orig/hisatgenotype_build_genome.py
+++ hisat2/hisatgenotype_build_genome.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2016, Daehwan Kim <infphilo@gmail.com>
@@ -75,11 +75,11 @@
                             "--genotype-vcf", "clinvar.vcf.gz",
                             "genome.fa", "/dev/null", "clinvar"]
             if verbose:
-                print >> sys.stderr, "\tRunning:", ' '.join(extract_cmd)
+                print("\tRunning:", ' '.join(extract_cmd), file=sys.stderr)
             proc = subprocess.Popen(extract_cmd, stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w'))
             proc.communicate()
             if not typing_common.check_files(CLINVAR_fnames):
-                print >> sys.stderr, "Error: extract variants from clinvar failed!"
+                print("Error: extract variants from clinvar failed!", file=sys.stderr)
                 sys.exit(1)
 
         # Read variants to be genotyped
@@ -106,11 +106,11 @@
                            "--intra-gap", str(intra_gap),
                            "genome.fa", "%s.txt" % commonvar_fbase, commonvar_fbase]
             if verbose:
-                print >> sys.stderr, "\tRunning:", ' '.join(extract_cmd)
+                print("\tRunning:", ' '.join(extract_cmd), file=sys.stderr)
             proc = subprocess.Popen(extract_cmd, stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w'))
             proc.communicate()
             if not typing_common.check_files(commonvar_fnames):
-                print >> sys.stderr, "Error: extract variants from clinvar failed!"
+                print("Error: extract variants from clinvar failed!", file=sys.stderr)
                 sys.exit(1)
 
         # Read variants to be genotyped
@@ -194,13 +194,13 @@
                     continue
 
                 out_str = "%s\t%s\t%s\t%d\t%s" % (var_id, var_type, chr, var_left + off, var_data)
-                print >> var_out_file, out_str
-                print >> index_var_out_file, out_str
+                print(out_str, file=var_out_file)
+                print(out_str, file=index_var_out_file)
 
                 if var_id in genotype_clnsig:
                     var_gene, clnsig = genotype_clnsig[var_id]
-                    print >> clnsig_out_file, "%s\t%s\t%s" % \
-                        (var_id, var_gene, clnsig)
+                    print("%s\t%s\t%s" % \
+                        (var_id, var_gene, clnsig), file=clnsig_out_file)
                 
                 chr_genotype_vari += 1
 
@@ -213,8 +213,8 @@
                     chr_genotype_hti += 1
                     continue
 
-                print >> haplotype_out_file, "ht%d\t%s\t%d\t%d\t%s" % \
-                    (haplotype_num, chr, ht_left + off, ht_right + off, ','.join(ht_vars))
+                print("ht%d\t%s\t%d\t%d\t%s" % \
+                    (haplotype_num, chr, ht_left + off, ht_right + off, ','.join(ht_vars)), file=haplotype_out_file)
                 chr_genotype_hti += 1
                 haplotype_num += 1
 
@@ -257,7 +257,7 @@
             assert left < chr_len and right < chr_len
             # Skipping overlapping genes
             if left < prev_right:
-                print >> sys.stderr, "Warning: skipping %s ..." % (name)
+                print("Warning: skipping %s ..." % (name), file=sys.stderr)
                 continue
 
             varID2htID = {}
@@ -270,12 +270,12 @@
                 out_chr_seq += chr_seq[prev_right:left]
 
             # Output gene (genotype_genome.gene)
-            print >> locus_out_file, "%s\t%s\t%s\t%d\t%d\t%s\t%s" % \
-                (family.upper(), name, chr, len(out_chr_seq), len(out_chr_seq) + length - 1, exon_str, strand)
+            print("%s\t%s\t%s\t%d\t%d\t%s\t%s" % \
+                (family.upper(), name, chr, len(out_chr_seq), len(out_chr_seq) + length - 1, exon_str, strand), file=locus_out_file)
 
             # Output coord (genotype_genome.coord)
-            print >> coord_out_file, "%s\t%d\t%d\t%d" % \
-                (chr, len(out_chr_seq), left, right - left + 1)
+            print("%s\t%d\t%d\t%d" % \
+                (chr, len(out_chr_seq), left, right - left + 1), file=coord_out_file)
             out_chr_seq += allele_seq
 
             # Output variants (genotype_genome.snp and genotype_genome.index.snp)
@@ -294,9 +294,9 @@
                     assert var_type == "insertion"
 
                 out_str = "%s\t%s\t%s\t%d\t%s" % (new_var_id, var_type, chr, new_var_left, var_data)
-                print >> var_out_file, out_str
+                print(out_str, file=var_out_file)
                 if var_id in index_var_ids:
-                    print >> index_var_out_file, out_str
+                    print(out_str, file=index_var_out_file)
                 var_num += 1
                 
             # Output haplotypes (genotype_genome.haplotype)
@@ -311,8 +311,8 @@
                 for var_id in ht_vars:
                     assert var_id in varID2htID
                     new_ht_vars.append(varID2htID[var_id])
-                print >> haplotype_out_file, "ht%d\t%s\t%d\t%d\t%s" % \
-                    (haplotype_num, chr, new_ht_left, new_ht_right, ','.join(new_ht_vars))
+                print("ht%d\t%s\t%d\t%d\t%s" % \
+                    (haplotype_num, chr, new_ht_left, new_ht_right, ','.join(new_ht_vars)), file=haplotype_out_file)
                 haplotype_num += 1
 
             # Output link information between alleles and variants (genotype_genome.link)
@@ -321,26 +321,26 @@
                 if var_id not in varID2htID:
                     continue
                 new_var_id = varID2htID[var_id]
-                print >> link_out_file, "%s\t%s" % (new_var_id, allele_names)
+                print("%s\t%s" % (new_var_id, allele_names), file=link_out_file)
                 
             off += (length - prev_length)
 
             prev_right = right + 1
 
         # Write the rest of the Vars
-        chr_genotype_vari, chr_genotype_hti, haplotype_num = add_vars(sys.maxint, sys.maxint, chr_genotype_vari, chr_genotype_hti, haplotype_num)            
+        chr_genotype_vari, chr_genotype_hti, haplotype_num = add_vars(sys.maxsize, sys.maxsize, chr_genotype_vari, chr_genotype_hti, haplotype_num)            
             
-        print >> coord_out_file, "%s\t%d\t%d\t%d" % \
-            (chr, len(out_chr_seq), prev_right, len(chr_seq) - prev_right)
+        print("%s\t%d\t%d\t%d" % \
+            (chr, len(out_chr_seq), prev_right, len(chr_seq) - prev_right), file=coord_out_file)
         out_chr_seq += chr_seq[prev_right:]
 
         assert len(out_chr_seq) == len(chr_seq) + off
 
         # Output chromosome sequence
-        print >> genome_out_file, ">%s" % (chr_full_name)
+        print(">%s" % (chr_full_name), file=genome_out_file)
         line_width = 60
         for s in range(0, len(out_chr_seq), line_width):
-            print >> genome_out_file, out_chr_seq[s:s+line_width]
+            print(out_chr_seq[s:s+line_width], file=genome_out_file)
 
     genome_out_file.close()
     locus_out_file.close()
@@ -355,7 +355,7 @@
     for database in database_list:
         for line in open("%s.partial" % database):
             allele_name = line.strip()
-            print >> partial_out_file, "%s\t%s" % (database.upper(), allele_name)
+            print("%s\t%s" % (database.upper(), allele_name), file=partial_out_file)
     partial_out_file.close()
 
     # Index genotype_genome.fa
@@ -371,11 +371,11 @@
                  "%s.fa" % base_fname,
                  "%s" % base_fname]
     if verbose:
-        print >> sys.stderr, "\tRunning:", ' '.join(build_cmd)
+        print("\tRunning:", ' '.join(build_cmd), file=sys.stderr)
         
     subprocess.call(build_cmd, stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w'))
     if not typing_common.check_files(hisat2_index_fnames):
-        print >> sys.stderr, "Error: indexing failed!  Perhaps, you may have forgotten to build hisat2 executables?"
+        print("Error: indexing failed!  Perhaps, you may have forgotten to build hisat2 executables?", file=sys.stderr)
         sys.exit(1)
 
         
@@ -424,7 +424,7 @@
 
     args = parser.parse_args()
     if args.inter_gap > args.intra_gap:
-        print >> sys.stderr, "Error: --inter-gap (%d) must be smaller than --intra-gap (%d)" % (args.inter_gap, args.intra_gap)
+        print("Error: --inter-gap (%d) must be smaller than --intra-gap (%d)" % (args.inter_gap, args.intra_gap), file=sys.stderr)
         sys.exit(1)
         
     if args.database_list == "":
@@ -433,7 +433,7 @@
         database_list = args.database_list.split(',')
 
     if args.use_clinvar and args.use_commonvar:
-        print >> sys.stderr, "Error: both --clinvar and --commonvar cannot be used together."
+        print("Error: both --clinvar and --commonvar cannot be used together.", file=sys.stderr)
         sys.exit(1)
         
         
--- hisat2.orig/hisatgenotype_extract_reads.py
+++ hisat2/hisatgenotype_extract_reads.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2017, Daehwan Kim <infphilo@gmail.com>
@@ -99,9 +99,9 @@
     # hisat2 graph index files
     genotype_fnames += ["%s.%d.ht2" % (base_fname, i+1) for i in range(8)]
     if not typing_common.check_files(genotype_fnames):        
-        print >> sys.stderr, "Error: %s related files do not exist as follows:" % base_fname
+        print("Error: %s related files do not exist as follows:" % base_fname, file=sys.stderr)
         for fname in genotype_fnames:
-            print >> sys.stderr, "\t%s" % fname
+            print("\t%s" % fname, file=sys.stderr)
         sys.exit(1)
 
     filter_region = len(database_list) > 0
@@ -164,7 +164,7 @@
             else:
                 fq_fname2 = "%s/%s.2.%s" % (read_dir, fq_fname_base, suffix)
             if not os.path.exists(fq_fname2):
-                print >> sys.stderr, "%s does not exist." % fq_fname2
+                print("%s does not exist." % fq_fname2, file=sys.stderr)
                 continue
         else:
             fq_fname2 = ""
@@ -179,7 +179,7 @@
                     continue
         count += 1
 
-        print >> sys.stderr, "\t%d: Extracting reads from %s" % (count, fq_fname_base)
+        print("\t%d: Extracting reads from %s" % (count, fq_fname_base), file=sys.stderr)
         def work(fq_fname_base,
                  fq_fname, 
                  fq_fname2, 
@@ -198,7 +198,7 @@
             else:
                 aligner_cmd += ["-U", fq_fname]
             if verbose:
-                print >> sys.stderr, "\t\trunning", ' '.join(aligner_cmd)
+                print("\t\trunning", ' '.join(aligner_cmd), file=sys.stderr)
             align_proc = subprocess.Popen(aligner_cmd,
                                           stdout=subprocess.PIPE,
                                           stderr=open("/dev/null", 'w'))
@@ -264,7 +264,7 @@
                     prev_read_name, extract_read, read1, read2 = read_name, False, [], []
 
                 if flag & 0x4 == 0 and NH == 1 and chr in region_loci:                    
-                    for region, loci in region_loci[chr].items():
+                    for region, loci in list(region_loci[chr].items()):
                         region = region.split('-')[0].lower()
                         _, _, loci_left, loci_right = loci
                         if pos >= loci_left and pos < loci_right:
@@ -289,7 +289,7 @@
                 if paired:
                     write_read(gzip_dic[region][1], prev_read_name, read2[0], read2[1])
 
-            for gzip1_proc, gzip2_proc in gzip_dic.values():
+            for gzip1_proc, gzip2_proc in list(gzip_dic.values()):
                 gzip1_proc.stdin.close()
                 if paired:
                     gzip2_proc.stdin.close()                        
@@ -376,7 +376,7 @@
     parser.add_argument("--max-sample",
                         dest="max_sample",
                         type=int,
-                        default=sys.maxint,
+                        default=sys.maxsize,
                         help="Number of samples to be extracted (default: sys.maxint)")
     parser.add_argument("--job-range",
                         dest="job_range",
@@ -398,17 +398,17 @@
         args.read_fname = [args.read_fname_U]
     elif args.read_fname_1 != "" or args.read_fname_2 != "":
         if args.read_fname_1 == "" or args.read_fname_2 == "":
-            print >> sys.stderr, "Error: please specify both -1 and -2."
+            print("Error: please specify both -1 and -2.", file=sys.stderr)
             sys.exit(1)
         args.read_fname = [args.read_fname_1, args.read_fname_2]
     else:
         args.read_fname = []
     if len(args.read_fname) == 0:
         if args.read_dir == "" or not os.path.exists(args.read_dir):
-            print >> sys.stderr, "Error: please specify --read-dir with an existing directory."
+            print("Error: please specify --read-dir with an existing directory.", file=sys.stderr)
             sys.exit(1)
         if args.out_dir == "":
-            print >> sys.stderr, "Error: please specify --out-dir with a directory name."
+            print("Error: please specify --out-dir with a directory name.", file=sys.stderr)
             sys.exit(1)
     job_range = []
     for num in args.job_range.split(','):
--- hisat2.orig/hisatgenotype_extract_vars.py
+++ hisat2/hisatgenotype_extract_vars.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2015, Daehwan Kim <infphilo@gmail.com>
@@ -163,8 +163,8 @@
             break
 
         if debug:
-            print >> sys.stderr, bp_i, bp_j, backbone_seq[bp_i-10:bp_i], backbone_seq[bp_i:bp_j], backbone_seq[bp_j:bp_j+10]
-            print >> sys.stderr, bp_i, bp_j, ''.join(seq[bp_i-10:bp_i]), ''.join(seq[bp_i:bp_j]), ''.join(seq[bp_j:bp_j+10])
+            print(bp_i, bp_j, backbone_seq[bp_i-10:bp_i], backbone_seq[bp_i:bp_j], backbone_seq[bp_j:bp_j+10], file=sys.stderr)
+            print(bp_i, bp_j, ''.join(seq[bp_i-10:bp_i]), ''.join(seq[bp_i:bp_j]), ''.join(seq[bp_j:bp_j+10]), file=sys.stderr)
         prev_i, prev_j = bp_i, bp_j
 
         while bp_i > 0 and seq[bp_i-1] in "ACGT" and backbone_seq[bp_j-1] in "ACGT":
@@ -182,7 +182,7 @@
 
         # DK - debugging purposes
         if debug:
-            print prev_i, prev_j, ''.join(seq[prev_i-10:prev_i]), ''.join(seq[prev_i:prev_j]), ''.join(seq[prev_j:prev_j+10])
+            print(prev_i, prev_j, ''.join(seq[prev_i-10:prev_i]), ''.join(seq[prev_i:prev_j]), ''.join(seq[prev_j:prev_j+10]))
 
     return ''.join(seq)
 
@@ -253,7 +253,7 @@
                                       stdout=subprocess.PIPE,
                                       stderr=open("/dev/null", 'w'))
         allele_id = ""
-        best_chr, best_left, best_right, best_AS, best_strand = "", -1, -1, -sys.maxint, ''
+        best_chr, best_left, best_right, best_AS, best_strand = "", -1, -1, -sys.maxsize, ''
         for line in align_proc.stdout:
             if line.startswith('@'):
                 continue
@@ -304,8 +304,8 @@
         assert allele_name != "" and strand != ''
         genes[gene] = allele_name
         gene_strand[gene] = strand
-        print >> sys.stderr, "%s-%s's reference allele is %s on '%s' strand of chromosome %s" % \
-            (base_fname.upper(), gene, allele_name, strand, chr)
+        print("%s-%s's reference allele is %s on '%s' strand of chromosome %s" % \
+            (base_fname.upper(), gene, allele_name, strand, chr), file=sys.stderr)
 
         assert chr != "" and left >= 0 and right > left
         if ext_seq_len > 0:
@@ -376,7 +376,7 @@
             continue
         tmp_locus_list.append(gene)
     locus_list = tmp_locus_list
-    for key in genes.keys():
+    for key in list(genes.keys()):
         if key in locus_list:
             continue
         del genes[key]
@@ -397,7 +397,7 @@
     input_file = open(base_fullpath_name + "_sequences.fa", 'w')
     num_vars, num_haplotypes = 0, 0
     full_alleles = {}
-    for gene, ref_gene in genes.items():
+    for gene, ref_gene in list(genes.items()):
         strand = gene_strand[gene]
         left_ext_seq, right_ext_seq = "", ""
         if gene in left_ext_seq_dic:
@@ -423,7 +423,7 @@
                         continue
 
                     if name in names:
-                        print >> sys.stderr, "Warning: %s is found more than once in Names" % (name)
+                        print("Warning: %s is found more than once in Names" % (name), file=sys.stderr)
                         continue
 
                     names[name] = len(names)
@@ -471,7 +471,7 @@
             MSA_fname = "hisatgenotype_db/%s/msf/%s_gen.msf" % (base_fname.upper(), gene)
             
         if not os.path.exists(MSA_fname):
-            print >> sys.stderr, "Warning: %s does not exist" % MSA_fname
+            print("Warning: %s does not exist" % MSA_fname, file=sys.stderr)
             continue
 
         names, seqs = read_MSF_file(MSA_fname, left_ext_seq, right_ext_seq)
@@ -490,7 +490,7 @@
                     seq_lens[seq_len] += 1
 
             max_seq_count = 0
-            for tmp_seq_len, tmp_seq_count in seq_lens.items():
+            for tmp_seq_len, tmp_seq_count in list(seq_lens.items()):
                 if tmp_seq_count > max_seq_count:
                     seq_len = tmp_seq_len
                     max_seq_count = tmp_seq_count
@@ -509,7 +509,7 @@
         if partial and base_fname == "hla":
             partial_MSA_fname = "hisatgenotype_db/HLA/msf/%s_nuc.msf" % gene
             if not os.path.exists(partial_MSA_fname):
-                print >> sys.stderr, "Warning: %s does not exist" % partial_MSA_fname
+                print("Warning: %s does not exist" % partial_MSA_fname, file=sys.stderr)
                 continue
             partial_names, partial_seqs = read_MSF_file(partial_MSA_fname)
 
@@ -550,7 +550,7 @@
                 ref_exons.append([ref_seq_map[left], ref_seq_map[right]])
                 next_exon_len = right - left + exon_len
                 if next_exon_len >= len(ref_partial_seq_map):
-                    print >> sys.stderr, "Warning: partial sequences (%s) seem to be incomplete" % gene
+                    print("Warning: partial sequences (%s) seem to be incomplete" % gene, file=sys.stderr)
                     complete = False
                     break
                 ref_partial_exons.append([ref_partial_seq_map[exon_len], ref_partial_seq_map[next_exon_len]])
@@ -566,7 +566,7 @@
                                                                                    partial_seq_len,
                                                                                    min_var_freq,
                                                                                    False) # Remove empty sequences?
-                for name, seq_id in partial_names.items():
+                for name, seq_id in list(partial_names.items()):
                     if name in names:
                         continue
                     seq = partial_seqs[seq_id]
@@ -618,17 +618,17 @@
             backbone_seq, backbone_freq = create_consensus_seq(seqs, seq_len, min_var_freq, True)
             seq_len = find_seq_len(seqs)
 
-        print >> sys.stderr, "%s: number of HLA alleles is %d." % (gene, len(names))
+        print("%s: number of HLA alleles is %d." % (gene, len(names)), file=sys.stderr)
 
         Vars = {}
-        for cmp_name, id in names.items():
+        for cmp_name, id in list(names.items()):
             if cmp_name == backbone_name:
                 continue
             assert id < len(seqs)
             cmp_seq = seqs[id]
             if len(cmp_seq) != seq_len:
-                print >> sys.stderr, "Warning: the length of %s (%d) is different from %d" % \
-                    (cmp_name, len(cmp_seq), seq_len)
+                print("Warning: the length of %s (%d) is different from %d" % \
+                    (cmp_name, len(cmp_seq), seq_len), file=sys.stderr)
                 continue
 
             # DK - debugging purposes
@@ -728,7 +728,7 @@
                 insertVar('D', deletion)
 
 
-        print >> sys.stderr, "Number of variants is %d." % (len(Vars.keys()))
+        print("Number of variants is %d." % (len(list(Vars.keys()))), file=sys.stderr)
 
         # Compare variants
         def cmp_varKey(a, b):
@@ -758,20 +758,20 @@
                 return int(a_data) - int(b_data)            
 
         Vars_ = {}
-        for key, values in Vars.items():
+        for key, values in list(Vars.items()):
             freq, names_ = values
             for name in names_:
                 if not name in Vars_:
                     Vars_[name] = [key]
                 else:
                     Vars_[name].append(key)
-        for name, vars in Vars_.items():
+        for name, vars in list(Vars_.items()):
             Vars_[name] = sorted(vars, cmp=cmp_varKey)
 
         # Sanity check -
         #    (1) Reconstruct the other sequences from the backbone sequence and variants and
         #    (2) Confirm these constructed sequences are the same as those input sequences.
-        for cmp_name, id in names.items():
+        for cmp_name, id in list(names.items()):
             if cmp_name == backbone_name:
                 continue
 
@@ -809,27 +809,27 @@
             assert id < len(seqs)
             cmp_seq = seqs[id].replace('.', '')
             if len(constr_seq) != len(cmp_seq):
-                print >> sys.stderr, "Error: reconstruction fails (%s)! Lengths different: %d vs. %d" % \
-                    (cmp_name, len(constr_seq), len(cmp_seq))
+                print("Error: reconstruction fails (%s)! Lengths different: %d vs. %d" % \
+                    (cmp_name, len(constr_seq), len(cmp_seq)), file=sys.stderr)
                 assert False
 
             # Sanity check
             for s in range(len(constr_seq)):
                 if constr_seq[s] != cmp_seq[s]:
-                    print >> sys.stderr, "Differ at %d: %s vs. %s (reconstruction vs. original)" % \
-                        (s, constr_seq[s], cmp_seq[s])
-                    print "%s:%s vs. %s:%s" % \
-                        (constr_seq[s-10:s], constr_seq[s:s+10], cmp_seq[s-10:s], cmp_seq[s:s+10])
+                    print("Differ at %d: %s vs. %s (reconstruction vs. original)" % \
+                        (s, constr_seq[s], cmp_seq[s]), file=sys.stderr)
+                    print("%s:%s vs. %s:%s" % \
+                        (constr_seq[s-10:s], constr_seq[s:s+10], cmp_seq[s-10:s], cmp_seq[s:s+10]))
 
             if constr_seq != cmp_seq.replace('.', ''):
-                print >> sys.stderr, "Error: reconstruction fails for %s" % (cmp_name)
+                print("Error: reconstruction fails for %s" % (cmp_name), file=sys.stderr)
                 assert False
 
         # Write the backbone sequences into a fasta file
-        print >> backbone_file, ">%s" % (backbone_name)
+        print(">%s" % (backbone_name), file=backbone_file)
         backbone_seq_ = backbone_seq.replace('.', '')
         for s in range(0, len(backbone_seq_), 60):
-            print >> backbone_file, backbone_seq_[s:s+60]
+            print(backbone_seq_[s:s+60], file=backbone_file)
 
         # Remap the backbone allele, which is sometimes slighly different from
         #   fasta version
@@ -845,7 +845,7 @@
         align_proc = subprocess.Popen(aligner_cmd,
                                       stdout=subprocess.PIPE,
                                       stderr=open("/dev/null", 'w'))
-        best_chr, best_left, best_right, best_AS = "", 0, 0, -sys.maxint
+        best_chr, best_left, best_right, best_AS = "", 0, 0, -sys.maxsize
         for line in align_proc.stdout:
             if line.startswith('@'):
                 continue
@@ -874,7 +874,7 @@
         chr, left, right = best_chr, best_left, best_right
         align_proc.communicate()
         if left == right:
-            print >> sys.stderr, "Warning: %s (%s) is not remapped" % (gene, ref_gene)
+            print("Warning: %s (%s) is not remapped" % (gene, ref_gene), file=sys.stderr)
             continue
         assert left < right
 
@@ -959,17 +959,17 @@
                     print cmp_exon_seq_[p:p+60]
                 """
                 if exon_seq_ != cmp_exon_seq_:
-                    print >> sys.stderr, "Waring: exonic sequences do not match (%s)" % gene
+                    print("Waring: exonic sequences do not match (%s)" % gene, file=sys.stderr)
         else:
             exon_str = "%d-%d" % (left, right - 1)
 
-        print >> locus_file, "%s\t%s\t%d\t%d\t%d\t%s\t%s" % \
-            (backbone_name, chr, left, right - 1, len(backbone_seq.replace('.', '')), exon_str, gene_strand[gene])
+        print("%s\t%s\t%d\t%d\t%d\t%s\t%s" % \
+            (backbone_name, chr, left, right - 1, len(backbone_seq.replace('.', '')), exon_str, gene_strand[gene]), file=locus_file)
 
         # Write
         #       (1) variants w.r.t the backbone sequences into a SNP file
         #       (2) pairs of a variant and the corresponding HLA allels into a LINK file    
-        keys = sorted(Vars.keys(), cmp=cmp_varKey)
+        keys = sorted(list(Vars.keys()), cmp=cmp_varKey)
         var2ID = {}
         for k in range(len(keys)):
             locus, type, data = keys[k].split('-')
@@ -986,20 +986,20 @@
             names_ = sorted(names_)            
             varID = "hv%d" % (num_vars)
             tmp_backbone_name = backbone_name
-            print >> var_file, "%s\t%s\t%s\t%d\t%s" % \
-                (varID, type_str, tmp_backbone_name, base_locus + locus, data)
+            print("%s\t%s\t%s\t%d\t%s" % \
+                (varID, type_str, tmp_backbone_name, base_locus + locus, data), file=var_file)
             if freq >= min_var_freq:
-                print >> var_index_file, "%s\t%s\t%s\t%d\t%s" % \
-                    (varID, type_str, tmp_backbone_name, base_locus + locus, data)
-            print >> var_freq_file, "%s\t%.2f" % (varID, freq)
-            print >> link_file, "%s\t%s" % (varID, ' '.join(names_))
+                print("%s\t%s\t%s\t%d\t%s" % \
+                    (varID, type_str, tmp_backbone_name, base_locus + locus, data), file=var_index_file)
+            print("%s\t%.2f" % (varID, freq), file=var_freq_file)
+            print("%s\t%s" % (varID, ' '.join(names_)), file=link_file)
             var2ID[keys[k]] = num_vars
             num_vars += 1
 
         add_seq_len = 0
         # Write haplotypes
         excluded_vars = set()
-        var_leftmost, var_rightmost = sys.maxint, -1
+        var_leftmost, var_rightmost = sys.maxsize, -1
         for k in range(len(keys)):
             key = keys[k]
             if Vars[key][0] < min_var_freq:
@@ -1134,7 +1134,7 @@
                         h_end += (int(h2_data) - 1)
                     assert h_begin <= h_end
                     h_new_begin = h_begin
-                    for h_j in reversed(range(0, h_i)):
+                    for h_j in reversed(list(range(0, h_i))):
                         hc = haplotypes[h_j].split('#')
                         hc_begin, hc_type, hc_data = hc[-1].split('-')
                         hc_begin = int(hc_begin)
@@ -1148,23 +1148,23 @@
                     assert h_new_begin <= h_begin
                     h_begin = h_new_begin
                 tmp_backbone_name = backbone_name
-                print >> haplotype_file, "ht%d\t%s\t%d\t%d\t%s" % \
-                    (num_haplotypes, tmp_backbone_name, base_locus + h_begin, base_locus + h_end, ','.join(varIDs))
+                print("ht%d\t%s\t%d\t%d\t%s" % \
+                    (num_haplotypes, tmp_backbone_name, base_locus + h_begin, base_locus + h_end, ','.join(varIDs)), file=haplotype_file)
                 num_haplotypes += 1
                 add_seq_len += (h_end - h_begin + 1)
             assert len(sanity_vars) == len(cur_vars)
                     
             i = j
 
-        print >> sys.stderr, "Length of additional sequences for haplotypes:", add_seq_len
+        print("Length of additional sequences for haplotypes:", add_seq_len, file=sys.stderr)
                     
         # Write all the sequences with dots removed into a file
-        for name, ID in names.items():
-            print >> input_file, ">%s" % (name)
+        for name, ID in list(names.items()):
+            print(">%s" % (name), file=input_file)
             assert ID < len(seqs)
             seq = seqs[ID].replace('.', '')
             for s in range(0, len(seq), 60):
-                print >> input_file, seq[s:s+60]
+                print(seq[s:s+60], file=input_file)
 
     backbone_file.close()
     locus_file.close()
@@ -1190,7 +1190,7 @@
 
     partial_file = open("%s.partial" % base_fullpath_name, 'w')
     for partial_allele in partial_allele_list:
-        print >> partial_file, partial_allele
+        print(partial_allele, file=partial_file)
     partial_file.close()
    
     
@@ -1253,7 +1253,7 @@
     else:
         locus_list = args.locus_list.split(',')
     if args.inter_gap > args.intra_gap:
-        print >> sys.stderr, "Error: --inter-gap (%d) must be smaller than --intra-gap (%d)" % (args.inter_gap, args.intra_gap)
+        print("Error: --inter-gap (%d) must be smaller than --intra-gap (%d)" % (args.inter_gap, args.intra_gap), file=sys.stderr)
         sys.exit(1)
              
     if args.base_fname.find('/') != -1:
--- hisat2.orig/hisatgenotype_hla_cyp.py
+++ hisat2/hisatgenotype_hla_cyp.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2015, Daehwan Kim <infphilo@gmail.com>
@@ -62,8 +62,8 @@
     def write_reads(reads, idx):
         read_file = open('hla_input_%d.fa' % idx, 'w')
         for read_i in range(len(reads)):
-            print >> read_file, ">%d" % (read_i + 1)
-            print >> read_file, reads[read_i]
+            print(">%d" % (read_i + 1), file=read_file)
+            print(reads[read_i], file=read_file)
         read_file.close()
     write_reads(HLA_reads_1, 1)
     write_reads(HLA_reads_2, 2)
@@ -106,7 +106,7 @@
                         "-2", "%s" % read_fname[1]]
 
     if verbose:
-        print >> sys.stderr, ' '.join(aligner_cmd)
+        print(' '.join(aligner_cmd), file=sys.stderr)
     align_proc = subprocess.Popen(aligner_cmd,
                                   stdout=subprocess.PIPE,
                                   stderr=open("/dev/null", 'w'))
@@ -145,7 +145,7 @@
 """ 
 def normalize(prob):
     total = sum(prob.values())
-    for allele, mass in prob.items():
+    for allele, mass in list(prob.items()):
         prob[allele] = mass / total
 
         
@@ -153,7 +153,7 @@
 """
 def prob_diff(prob1, prob2):
     diff = 0.0
-    for allele in prob1.keys():
+    for allele in list(prob1.keys()):
         if allele in prob2:
             diff += abs(prob1[allele] - prob2[allele])
         else:
@@ -182,15 +182,15 @@
                      HLA_length):
     def normalize2(prob, length):
         total = 0
-        for allele, mass in prob.items():
+        for allele, mass in list(prob.items()):
             assert allele in length
             total += (mass / length[allele])
-        for allele, mass in prob.items():
+        for allele, mass in list(prob.items()):
             assert allele in length
             prob[allele] = mass / length[allele] / total
 
     HLA_prob, HLA_prob_next = {}, {}
-    for cmpt, count in HLA_cmpt.items():
+    for cmpt, count in list(HLA_cmpt.items()):
         alleles = cmpt.split('-')
         for allele in alleles:
             if allele not in HLA_prob:
@@ -201,7 +201,7 @@
     normalize(HLA_prob)
     def next_prob(HLA_cmpt, HLA_prob, HLA_length):
         HLA_prob_next = {}
-        for cmpt, count in HLA_cmpt.items():
+        for cmpt, count in list(HLA_cmpt.items()):
             alleles = cmpt.split('-')
             alleles_prob = 0.0
             for allele in alleles:
@@ -221,11 +221,11 @@
         diff = prob_diff(HLA_prob, HLA_prob_next)
         HLA_prob = HLA_prob_next
         iter += 1
-    for allele, prob in HLA_prob.items():
+    for allele, prob in list(HLA_prob.items()):
         allele_len = HLA_length[allele]
         HLA_prob[allele] /= float(allele_len)
     normalize(HLA_prob)
-    HLA_prob = [[allele, prob] for allele, prob in HLA_prob.items()]
+    HLA_prob = [[allele, prob] for allele, prob in list(HLA_prob.items())]
     HLA_prob = sorted(HLA_prob, cmp=HLA_prob_cmp)
     return HLA_prob
 
@@ -235,11 +235,11 @@
 def joint_abundance(HLA_cmpt,
                     HLA_length):
     allele_names = set()
-    for cmpt in HLA_cmpt.keys():
+    for cmpt in list(HLA_cmpt.keys()):
         allele_names |= set(cmpt.split('-'))
     
     HLA_prob, HLA_prob_next = {}, {}
-    for cmpt, count in HLA_cmpt.items():
+    for cmpt, count in list(HLA_cmpt.items()):
         alleles = cmpt.split('-')
         for allele1 in alleles:
             for allele2 in allele_names:
@@ -256,7 +256,7 @@
 
     # Choose top allele pairs
     def choose_top_alleles(HLA_prob):
-        HLA_prob_list = [[allele_pair, prob] for allele_pair, prob in HLA_prob.items()]
+        HLA_prob_list = [[allele_pair, prob] for allele_pair, prob in list(HLA_prob.items())]
         HLA_prob_list = sorted(HLA_prob_list, cmp=HLA_prob_cmp)
         HLA_prob = {}
         best_prob = HLA_prob_list[0][1]
@@ -271,15 +271,15 @@
 
     def next_prob(HLA_cmpt, HLA_prob):
         HLA_prob_next = {}
-        for cmpt, count in HLA_cmpt.items():
+        for cmpt, count in list(HLA_cmpt.items()):
             alleles = cmpt.split('-')
             prob = 0.0
             for allele in alleles:
-                for allele_pair in HLA_prob.keys():
+                for allele_pair in list(HLA_prob.keys()):
                     if allele in allele_pair:
                         prob += HLA_prob[allele_pair]
             for allele in alleles:
-                for allele_pair in HLA_prob.keys():
+                for allele_pair in list(HLA_prob.keys()):
                     if not allele in allele_pair:
                         continue
                     if allele_pair not in HLA_prob_next:
@@ -296,7 +296,7 @@
         HLA_prob = choose_top_alleles(HLA_prob)
         iter += 1
 
-    HLA_prob = [[allele_pair, prob] for allele_pair, prob in HLA_prob.items()]
+    HLA_prob = [[allele_pair, prob] for allele_pair, prob in list(HLA_prob.items())]
     HLA_prob = sorted(HLA_prob, cmp=HLA_prob_cmp)
     return HLA_prob
 
@@ -350,9 +350,9 @@
         test_passed = {}
     for aligner, index_type in aligners:
         if index_type == "graph":
-            print >> sys.stderr, "\n\t\t%s %s on %s" % (aligner, index_type, reference_type)
+            print("\n\t\t%s %s on %s" % (aligner, index_type, reference_type), file=sys.stderr)
         else:
-            print >> sys.stderr, "\n\t\t%s %s" % (aligner, index_type)
+            print("\n\t\t%s %s" % (aligner, index_type), file=sys.stderr)
 
         if alignment_fname == "":
             # Align reads, and sort the alignments into a BAM file
@@ -448,8 +448,8 @@
                     debug = False
                     if read_id in ["2339"] and False:
                         debug = True
-                        print "read_id: %s)" % read_id, pos, cigar_str, "NM:", NM, MD, Zs
-                        print "            ", read_seq
+                        print("read_id: %s)" % read_id, pos, cigar_str, "NM:", NM, MD, Zs)
+                        print("            ", read_seq)
 
                     vars = []
                     if Zs:
@@ -545,7 +545,7 @@
                     def add_stat(HLA_cmpt, HLA_counts, HLA_count_per_read, exon = True):
                         max_count = max(HLA_count_per_read.values())
                         cur_cmpt = set()
-                        for allele, count in HLA_count_per_read.items():
+                        for allele, count in list(HLA_count_per_read.items()):
                             if count < max_count:
                                 continue
                             if allele in exclude_allele_list:
@@ -563,7 +563,7 @@
                         alleles = ["", ""]
                         # alleles = ["B*40:304", "B*40:02:01"]
                         allele1_found, allele2_found = False, False
-                        for allele, count in HLA_count_per_read.items():
+                        for allele, count in list(HLA_count_per_read.items()):
                             if count < max_count:
                                 continue
                             if allele == alleles[0]:
@@ -571,13 +571,13 @@
                             elif allele == alleles[1]:
                                 allele2_found = True
                         if allele1_found != allele2_found:
-                            print alleles[0], HLA_count_per_read[alleles[0]]
-                            print alleles[1], HLA_count_per_read[alleles[1]]
+                            print(alleles[0], HLA_count_per_read[alleles[0]])
+                            print(alleles[1], HLA_count_per_read[alleles[1]])
                             if allele1_found:
-                                print ("%s\tread_id %s - %d vs. %d]" % (alleles[0], prev_read_id, max_count, HLA_count_per_read[alleles[1]]))
+                                print(("%s\tread_id %s - %d vs. %d]" % (alleles[0], prev_read_id, max_count, HLA_count_per_read[alleles[1]])))
                             else:
-                                print ("%s\tread_id %s - %d vs. %d]" % (alleles[1], prev_read_id, max_count, HLA_count_per_read[alleles[0]]))
-                            print read_seq
+                                print(("%s\tread_id %s - %d vs. %d]" % (alleles[1], prev_read_id, max_count, HLA_count_per_read[alleles[0]])))
+                            print(read_seq)
 
                         cur_cmpt = sorted(list(cur_cmpt))
                         cur_cmpt = '-'.join(cur_cmpt)
@@ -609,11 +609,11 @@
                             # daehwan - for debugging purposes
                             if debug:
                                 if allele in ["DQA1*05:05:01:01", "DQA1*05:05:01:02"]:
-                                    print allele, add, var_id
+                                    print(allele, add, var_id)
 
                     # Decide which allele(s) a read most likely came from
                     # also sanity check - read length, cigar string, and MD string
-                    for var_id, data in Vars[gene].items():
+                    for var_id, data in list(Vars[gene].items()):
                         var_type, var_pos, var_data = data
                         if var_type != "deletion":
                             continue
@@ -637,13 +637,13 @@
                                             add_count(var_id, -1)
                                             # daehwan - for debugging purposes
                                             if debug:
-                                                print cmp, var_id, Links[var_id]
+                                                print(cmp, var_id, Links[var_id])
                                     elif var_type == "deletion":
                                         del_len = int(var_data)
                                         if ref_pos < var_pos and ref_pos + length > var_pos + del_len:
                                             # daehwan - for debugging purposes
                                             if debug:
-                                                print cmp, var_id, Links[var_id], -1, Vars[gene][var_id]
+                                                print(cmp, var_id, Links[var_id], -1, Vars[gene][var_id])
                                             # Check if this might be one of the two tandem repeats (the same left coordinate)
                                             cmp_left, cmp_right = cmp[1], cmp[1] + cmp[2]
                                             test1_seq1 = ref_seq[cmp_left:cmp_right]
@@ -657,7 +657,7 @@
                                                 add_count(var_id, -1)
                                     else:
                                         if debug:
-                                            print cmp, var_id, Links[var_id], -1
+                                            print(cmp, var_id, Links[var_id], -1)
                                         add_count(var_id, -1)
                                 var_idx += 1
 
@@ -678,7 +678,7 @@
                                         if var_data == read_base:
                                             # daehwan - for debugging purposes
                                             if debug:
-                                                print cmp, var_id, 1, var_data, read_base, Links[var_id]
+                                                print(cmp, var_id, 1, var_data, read_base, Links[var_id])
 
                                             # daehwan - for debugging purposes
                                             if False:
@@ -701,8 +701,8 @@
                             var_idx = lower_bound(Var_list[gene], ref_pos)
                             # daehwan - for debugging purposes
                             if debug:
-                                print left_pos, cigar_str, MD, vars
-                                print ref_pos, ins_seq, Var_list[gene][var_idx], Vars[gene][Var_list[gene][var_idx][1]]
+                                print(left_pos, cigar_str, MD, vars)
+                                print(ref_pos, ins_seq, Var_list[gene][var_idx], Vars[gene][Var_list[gene][var_idx][1]])
                                 # sys.exit(1)
                             while var_idx < len(Var_list[gene]):
                                 var_pos, var_id = Var_list[gene][var_idx]
@@ -714,7 +714,7 @@
                                         if var_data == ins_seq:
                                             # daehwan - for debugging purposes
                                             if debug:
-                                                print cmp, var_id, 1, Links[var_id]
+                                                print(cmp, var_id, 1, Links[var_id])
                                             add_count(var_id, 1)
                                 var_idx += 1
 
@@ -750,8 +750,8 @@
                                         var_len = int(var_data)
                                         if var_len == length:
                                             if debug:
-                                                print cmp, var_id, 1, Links[var_id]
-                                                print ref_seq[var_pos - 10:var_pos], ref_seq[var_pos:var_pos+int(var_data)], ref_seq[var_pos+int(var_data):var_pos+int(var_data)+10]
+                                                print(cmp, var_id, 1, Links[var_id])
+                                                print(ref_seq[var_pos - 10:var_pos], ref_seq[var_pos:var_pos+int(var_data)], ref_seq[var_pos+int(var_data):var_pos+int(var_data)+10])
                                             add_count(var_id, 1)
                                 var_idx += 1
 
@@ -782,9 +782,9 @@
                     if read_pos != len(read_seq) or \
                             cmp_cigar_str != cigar_str or \
                             cmp_MD != MD:
-                        print >> sys.stderr, "Error:", cigar_str, MD
-                        print >> sys.stderr, "\tcomputed:", cmp_cigar_str, cmp_MD
-                        print >> sys.stderr, "\tcmp list:", cmp_list
+                        print("Error:", cigar_str, MD, file=sys.stderr)
+                        print("\tcomputed:", cmp_cigar_str, cmp_MD, file=sys.stderr)
+                        print("\tcmp list:", cmp_list, file=sys.stderr)
                         assert False            
 
                     prev_read_id = read_id
@@ -887,7 +887,7 @@
                 if alleles:
                     add_alleles(alleles)
 
-            HLA_counts = [[allele, count] for allele, count in HLA_counts.items()]
+            HLA_counts = [[allele, count] for allele, count in list(HLA_counts.items())]
             def HLA_count_cmp(a, b):
                 if a[1] != b[1]:
                     return b[1] - a[1]
@@ -903,7 +903,7 @@
                     found = False
                     for test_HLA_name in test_HLA_names:
                         if count[0] == test_HLA_name:
-                            print >> sys.stderr, "\t\t\t*** %d ranked %s (count: %d)" % (count_i + 1, test_HLA_name, count[1])
+                            print("\t\t\t*** %d ranked %s (count: %d)" % (count_i + 1, test_HLA_name, count[1]), file=sys.stderr)
                             found = True
                             """
                             if count_i > 0 and HLA_counts[0][1] > count[1]:
@@ -913,12 +913,12 @@
                                 test_passed += 1
                             """
                     if count_i < 5 and not found:
-                        print >> sys.stderr, "\t\t\t\t%d %s (count: %d)" % (count_i + 1, count[0], count[1])
+                        print("\t\t\t\t%d %s (count: %d)" % (count_i + 1, count[0], count[1]), file=sys.stderr)
                 else:
-                    print >> sys.stderr, "\t\t\t\t%d %s (count: %d)" % (count_i + 1, count[0], count[1])
+                    print("\t\t\t\t%d %s (count: %d)" % (count_i + 1, count[0], count[1]), file=sys.stderr)
                     if count_i >= 9:
                         break
-            print >> sys.stderr
+            print(file=sys.stderr)
 
             HLA_prob = single_abundance(HLA_cmpt, HLA_lengths[gene])
 
@@ -937,7 +937,7 @@
                                     rank_i -= 1
                                 else:
                                     break
-                            print >> sys.stderr, "\t\t\t*** %d ranked %s (abundance: %.2f%%)" % (rank_i + 1, test_HLA_name, prob[1] * 100.0)
+                            print("\t\t\t*** %d ranked %s (abundance: %.2f%%)" % (rank_i + 1, test_HLA_name, prob[1] * 100.0), file=sys.stderr)
                             if rank_i < len(success):
                                 success[rank_i] = True
                             found_list[name_i] = True
@@ -945,12 +945,12 @@
                     if not False in found_list:
                         break
                 if not found:
-                    print >> sys.stderr, "\t\t\t\t%d ranked %s (abundance: %.2f%%)" % (prob_i + 1, prob[0], prob[1] * 100.0)
+                    print("\t\t\t\t%d ranked %s (abundance: %.2f%%)" % (prob_i + 1, prob[0], prob[1] * 100.0), file=sys.stderr)
                     if best_alleles and prob_i < 2:
-                        print >> sys.stdout, "SingleModel %s (abundance: %.2f%%)" % (prob[0], prob[1] * 100.0)
+                        print("SingleModel %s (abundance: %.2f%%)" % (prob[0], prob[1] * 100.0), file=sys.stdout)
                 if not simulation and prob_i >= 9:
                     break
-            print >> sys.stderr
+            print(file=sys.stderr)
 
             if len(test_HLA_names) == 2 or not simulation:
                 HLA_prob = joint_abundance(HLA_cmpt, HLA_lengths[gene])
@@ -961,7 +961,7 @@
                     allele_pair, prob = HLA_prob[prob_i]
                     allele1, allele2 = allele_pair.split('-')
                     if best_alleles and prob_i < 1:
-                        print >> sys.stdout, "PairModel %s (abundance: %.2f%%)" % (allele_pair, prob * 100.0)
+                        print("PairModel %s (abundance: %.2f%%)" % (allele_pair, prob * 100.0), file=sys.stdout)
                     if simulation:
                         if allele1 in test_HLA_names and allele2 in test_HLA_names:
                             rank_i = prob_i
@@ -970,14 +970,14 @@
                                     rank_i -= 1
                                 else:
                                     break
-                            print >> sys.stderr, "\t\t\t*** %d ranked %s (abundance: %.2f%%)" % (rank_i + 1, allele_pair, prob * 100.0)
+                            print("\t\t\t*** %d ranked %s (abundance: %.2f%%)" % (rank_i + 1, allele_pair, prob * 100.0), file=sys.stderr)
                             if rank_i == 0:
                                 success[0] = True
                             break
-                    print >> sys.stderr, "\t\t\t\t%d ranked %s (abundance: %.2f%%)" % (prob_i + 1, allele_pair, prob * 100.0)
+                    print("\t\t\t\t%d ranked %s (abundance: %.2f%%)" % (prob_i + 1, allele_pair, prob * 100.0), file=sys.stderr)
                     if not simulation and prob_i >= 9:
                         break
-                print >> sys.stderr
+                print(file=sys.stderr)
 
                 # Li's method
                 """
@@ -1149,7 +1149,7 @@
             extract_cmd += ["--hla-list", ','.join(hla_list)]
 
         if len(exclude_allele_list) > 0:
-            print exclude_allele_list
+            print(exclude_allele_list)
             extract_cmd += ["--exclude-allele-list", ",".join(exclude_allele_list)]
 
         if len(base_fname) > 3:
@@ -1160,12 +1160,12 @@
         extract_cmd += ["--inter-gap", "30",
                         "--intra-gap", "50"]
         if verbose:
-            print >> sys.stderr, "\tRunning:", ' '.join(extract_cmd)
+            print("\tRunning:", ' '.join(extract_cmd), file=sys.stderr)
         proc = subprocess.Popen(extract_cmd, stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w'))
         proc.communicate()
         
         if not check_files(HLA_fnames):
-            print >> sys.stderr, "Error: extract_HLA_vars failed!"
+            print("Error: extract_HLA_vars failed!", file=sys.stderr)
             sys.exit(1)
             
     for aligner, index_type in aligners:
@@ -1181,11 +1181,11 @@
                              HLA_fnames[0],
                              "%s.graph" % base_fname]
                 if verbose:
-                    print >> sys.stderr, "\tRunning:", ' '.join(build_cmd)
+                    print("\tRunning:", ' '.join(build_cmd), file=sys.stderr)
                 proc = subprocess.Popen(build_cmd, stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w'))
                 proc.communicate()        
                 if not check_files(HLA_hisat2_graph_index_fnames):
-                    print >> sys.stderr, "Error: indexing HLA failed!  Perhaps, you may have forgotten to build hisat2 executables?"
+                    print("Error: indexing HLA failed!  Perhaps, you may have forgotten to build hisat2 executables?", file=sys.stderr)
                     sys.exit(1)
 
         # Build HISAT2 linear indexes based on the above information
@@ -1199,7 +1199,7 @@
                 proc = subprocess.Popen(build_cmd, stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w'))
                 proc.communicate()        
                 if not check_files(HLA_hisat2_linear_index_fnames):
-                    print >> sys.stderr, "Error: indexing HLA failed!"
+                    print("Error: indexing HLA failed!", file=sys.stderr)
                     sys.exit(1)
 
         # Build Bowtie2 indexes based on the above information
@@ -1214,7 +1214,7 @@
                 proc = subprocess.Popen(build_cmd, stdout=open("/dev/null", 'w'))
                 proc.communicate()        
                 if not check_files(HLA_bowtie2_index_fnames):
-                    print >> sys.stderr, "Error: indexing HLA failed!"
+                    print("Error: indexing HLA failed!", file=sys.stderr)
                     sys.exit(1)
         
     # Read partial alleles from hla.data (temporary)
@@ -1249,12 +1249,12 @@
             extract_cmd += ["--inter-gap", "30",
                             "--intra-gap", "50"]
             if verbose:
-                print >> sys.stderr, "\tRunning:", ' '.join(extract_cmd)
+                print("\tRunning:", ' '.join(extract_cmd), file=sys.stderr)
             proc = subprocess.Popen(extract_cmd, stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w'))
             proc.communicate()
             
             if not os.path.exists("./Default-HLA/hla_backbone.fa"):
-                print >> sys.stderr, "Error: extract_HLA_vars (Default) failed!"
+                print("Error: extract_HLA_vars (Default) failed!", file=sys.stderr)
                 sys.exit(1)
     
     # Read HLA alleles (names and sequences)
@@ -1278,14 +1278,14 @@
     
     # HLA gene alleles
     HLA_names = {}
-    for HLA_gene, data in HLAs.items():
+    for HLA_gene, data in list(HLAs.items()):
         HLA_names[HLA_gene] = list(data.keys())
 
     # HLA gene allele lengths
     HLA_lengths = {}
-    for HLA_gene, HLA_alleles in HLAs.items():
+    for HLA_gene, HLA_alleles in list(HLAs.items()):
         HLA_lengths[HLA_gene] = {}
-        for allele_name, seq in HLA_alleles.items():
+        for allele_name, seq in list(HLA_alleles.items()):
             HLA_lengths[HLA_gene][allele_name] = len(seq)
 
     # Construct excluded alleles (Via default backbone data)
@@ -1296,8 +1296,8 @@
         read_HLA_alleles("./Default-HLA/hla_backbone.fa",HLAs_default)
         read_HLA_alleles("./Default-HLA/hla_sequences.fa",HLAs_default)
         
-        for HLA_gene, HLA_alleles in HLAs_default.items():
-            for allele_name, seq in HLA_alleles.items():
+        for HLA_gene, HLA_alleles in list(HLAs_default.items()):
+            for allele_name, seq in list(HLA_alleles.items()):
                 if allele_name in default_allele_list:
                     HLA_lengths[HLA_gene][allele_name] = len(seq)
 
@@ -1308,7 +1308,7 @@
         pos = int(pos)
         if reference_type != "gene":
             allele, dist = None, 0
-            for tmp_gene, values in refHLA_loci.items():
+            for tmp_gene, values in list(refHLA_loci.items()):
                 allele_name, chr, left, right, exons = values
                 if allele == None:
                     allele = allele_name
@@ -1331,7 +1331,7 @@
         Vars[gene][var_id] = [var_type, pos - left, data]
         Var_list[gene].append([pos - left, var_id])
         
-    for gene, in_var_list in Var_list.items():
+    for gene, in_var_list in list(Var_list.items()):
         Var_list[gene] = sorted(in_var_list)
         
     Links = {}
@@ -1356,7 +1356,7 @@
         if base_fname == "hla":
             genes = list(set(hla_list) & set(HLA_names.keys()))
         else:
-            genes = HLA_names.keys()
+            genes = list(HLA_names.keys())
             
         if basic_test:
             for gene in genes:
@@ -1392,7 +1392,7 @@
                 if str(test_i + 1) not in daehwan_test_ids:
                     continue
 
-            print >> sys.stderr, "Test %d" % (test_i + 1)
+            print("Test %d" % (test_i + 1), file=sys.stderr)
             test_HLA_list = test_list[test_i]
            
             # daehwan - for debugging purposes
@@ -1403,12 +1403,12 @@
                         gene = test_HLA_name.split('*')[0]
                         test_HLA_seq = HLAs_default[gene][test_HLA_name]
                         seq_type = "partial" if test_HLA_name in partial_alleles else "full"
-                        print >> sys.stderr, "\t%s - %d bp (%s sequence)" % (test_HLA_name, len(test_HLA_seq), seq_type)
+                        print("\t%s - %d bp (%s sequence)" % (test_HLA_name, len(test_HLA_seq), seq_type), file=sys.stderr)
                         continue
                     gene = test_HLA_name.split('*')[0]
                     test_HLA_seq = HLAs[gene][test_HLA_name]
                     seq_type = "partial" if test_HLA_name in partial_alleles else "full"
-                    print >> sys.stderr, "\t%s - %d bp (%s sequence)" % (test_HLA_name, len(test_HLA_seq), seq_type)
+                    print("\t%s - %d bp (%s sequence)" % (test_HLA_name, len(test_HLA_seq), seq_type), file=sys.stderr)
             if custom_allele_check:
                 simulate_reads(HLAs_default, test_HLA_list, simulate_interval)
             else:
@@ -1446,24 +1446,24 @@
                                          best_alleles,
                                          verbose)
 
-            for aligner_type, passed in tmp_test_passed.items():
+            for aligner_type, passed in list(tmp_test_passed.items()):
                 if aligner_type in test_passed:
                     test_passed[aligner_type] += passed
                 else:
                     test_passed[aligner_type] = passed
 
-                print >> sys.stderr, "\t\tPassed so far: %d/%d (%.2f%%)" % (test_passed[aligner_type], test_i + 1, (test_passed[aligner_type] * 100.0 / (test_i + 1)))
+                print("\t\tPassed so far: %d/%d (%.2f%%)" % (test_passed[aligner_type], test_i + 1, (test_passed[aligner_type] * 100.0 / (test_i + 1))), file=sys.stderr)
 
 
-        for aligner_type, passed in test_passed.items():
-            print >> sys.stderr, "%s:\t%d/%d passed (%.2f%%)" % (aligner_type, passed, len(test_list), passed * 100.0 / len(test_list))
+        for aligner_type, passed in list(test_passed.items()):
+            print("%s:\t%d/%d passed (%.2f%%)" % (aligner_type, passed, len(test_list), passed * 100.0 / len(test_list)), file=sys.stderr)
     
     else: # With real reads or BAMs
         if base_fname == "hla":
             gene_list = hla_list
         else:
-            gene_list = Vars.keys()
-        print >> sys.stderr, "\t", ' '.join(gene_list)
+            gene_list = list(Vars.keys())
+        print("\t", ' '.join(gene_list), file=sys.stderr)
 
         fastq = True
         HLA_typing(ex_path,
@@ -1581,11 +1581,11 @@
 
     args = parser.parse_args()
     if not args.reference_type in ["gene", "chromosome", "genome"]:
-        print >> sys.stderr, "Error: --reference-type (%s) must be one of gene, chromosome, and genome." % (args.reference_type)
+        print("Error: --reference-type (%s) must be one of gene, chromosome, and genome." % (args.reference_type), file=sys.stderr)
         sys.exit(1)
     args.hla_list = args.hla_list.split(',')
     if args.aligners == "":
-        print >> sys.stderr, "Error: --aligners must be non-empty."
+        print("Error: --aligners must be non-empty.", file=sys.stderr)
         sys.exit(1)    
     args.aligners = args.aligners.split(',')
     for i in range(len(args.aligners)):
@@ -1596,7 +1596,7 @@
         args.read_fname = []
     if args.alignment_fname != "" and \
             not os.path.exists(args.alignment_fname):
-        print >> sys.stderr, "Error: %s doesn't exist." % args.alignment_fname
+        print("Error: %s doesn't exist." % args.alignment_fname, file=sys.stderr)
         sys.exit(1)
     
     if len(args.default_allele_list) > 0:
@@ -1621,11 +1621,11 @@
                 extract_cmd += ["--inter-gap", "30",
                                 "--intra-gap", "50"]
                 if verbose:
-                    print >> sys.stderr, "\tRunning:", ' '.join(extract_cmd)
+                    print("\tRunning:", ' '.join(extract_cmd), file=sys.stderr)
                 proc = subprocess.Popen(extract_cmd, stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w'))
                 proc.communicate()
                 if not os.path.exists("./Default-HLA/hla_backbone.fa"):
-                    print >> sys.stderr, "Error: extract_HLA_vars (Default) failed!"
+                    print("Error: extract_HLA_vars (Default) failed!", file=sys.stderr)
                     sys.exit(1)
        
             HLAs_default = {}
--- hisat2.orig/hisatgenotype_locus.py
+++ hisat2/hisatgenotype_locus.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Copyright 2015, Daehwan Kim <infphilo@gmail.com>
 #
@@ -49,7 +49,7 @@
 """
 def get_exonic_vars(Vars, exons):
     vars = set()
-    for var_id, var in Vars.items():
+    for var_id, var in list(Vars.items()):
         var_type, var_left, var_data = var
         var_right = var_left
         if var_type == "deletion":
@@ -66,7 +66,7 @@
 """
 def get_rep_alleles(Links, exon_vars):
     allele_vars = {}
-    for var, alleles in Links.items():
+    for var, alleles in list(Links.items()):
         if var not in exon_vars:
             continue
         for allele in alleles:
@@ -75,7 +75,7 @@
             allele_vars[allele].add(var)
 
     allele_groups = {}
-    for allele, vars in allele_vars.items():
+    for allele, vars in list(allele_vars.items()):
         vars = '-'.join(vars)
         if vars not in allele_groups:
             allele_groups[vars] = []
@@ -83,7 +83,7 @@
 
     allele_reps = {} # allele representatives
     allele_rep_groups = {} # allele groups by allele representatives
-    for allele_members in allele_groups.values():
+    for allele_members in list(allele_groups.values()):
         assert len(allele_members) > 0
         allele_rep = allele_members[0]
         allele_rep_groups[allele_rep] = allele_members
@@ -105,8 +105,8 @@
                   cmp_list,
                   debug = False):
     if debug:
-        print >> sys.stderr, cmp_list
-        print >> sys.stderr, read_seq
+        print(cmp_list, file=sys.stderr)
+        print(read_seq, file=sys.stderr)
 
     num_correction = 0
     i = 0
@@ -161,7 +161,7 @@
             nt_set = mpileup[left][0]
 
             if debug:
-                print >> sys.stderr, left, read_bp, ref_bp, mpileup[left]
+                print(left, read_bp, ref_bp, mpileup[left], file=sys.stderr)
 
             if len(nt_set) > 0 and read_bp not in nt_set:
                 read_bp = 'N' if len(nt_set) > 1 else nt_set[0]
@@ -186,8 +186,8 @@
                         var_idx += 1
 
                 if debug:
-                    print >> sys.stderr, left, read_bp, ref_bp, mpileup[left]
-                    print >> sys.stderr, cmp_list[i]
+                    print(left, read_bp, ref_bp, mpileup[left], file=sys.stderr)
+                    print(cmp_list[i], file=sys.stderr)
 
         read_pos += length
         i += 1
@@ -205,8 +205,8 @@
         i += 1
 
     if debug:
-        print >> sys.stderr, cmp_list
-        print >> sys.stderr, read_seq
+        print(cmp_list, file=sys.stderr)
+        print(read_seq, file=sys.stderr)
                             
     return cmp_list, read_seq, num_correction
 
@@ -249,9 +249,9 @@
     for aligner, index_type in aligners:
         for f_ in [sys.stderr, report_file]:
             if index_type == "graph":
-                print >> f_, "\n\t\t%s %s" % (aligner, index_type)
+                print("\n\t\t%s %s" % (aligner, index_type), file=f_)
             else:
-                print >> f_, "\n\t\t%s %s" % (aligner, index_type)
+                print("\n\t\t%s %s" % (aligner, index_type), file=f_)
 
         remove_alignment_file = False
         if alignment_fname == "":
@@ -453,7 +453,7 @@
 
             def haplotype_alts_list(haplotype_alts, left = True):
                 haplotype_list = []
-                for haplotype in haplotype_alts.keys():
+                for haplotype in list(haplotype_alts.keys()):
                     if left:
                         pos = int(haplotype.split('-')[-1])
                     else:
@@ -535,7 +535,7 @@
                             expected_inter_dist = fragment_len - read_len * 2
                         """
                             
-                        best_diff = sys.maxint
+                        best_diff = sys.maxsize
                         picked = []                                
                         for left_ht_str in left_positive_hts:
                             left_ht = left_ht_str.split('-')
@@ -604,7 +604,7 @@
                         assert ht_left >= e_left
                         if ht_right > e_right:
                             split = False
-                            for i in reversed(range(1, len(new_ht) - 1)):
+                            for i in reversed(list(range(1, len(new_ht) - 1))):
                                 var_id = new_ht[i]
                                 type, right, data = gene_vars[var_id]
                                 if type == "deletion":
@@ -657,8 +657,8 @@
                     # Unalined?
                     if flag & 0x4 != 0:
                         if simulation and verbose >= 2:
-                            print "Unaligned"
-                            print "\t", line
+                            print("Unaligned")
+                            print("\t", line)
                         continue
 
                     # Concordantly mapped?
@@ -865,7 +865,7 @@
                             # Check if this deletion is artificial alignment
                             if right_pos < len(mpileup):
                                 del_count, nt_count = 0, 0
-                                for nt, value in mpileup[right_pos][1].items():
+                                for nt, value in list(mpileup[right_pos][1].items()):
                                     count = value[0]
                                     if nt == 'D':
                                         del_count += count
@@ -959,7 +959,7 @@
                     def add_stat(Gene_cmpt, Gene_counts, Gene_count_per_read, include_alleles = set()):
                         max_count = max(Gene_count_per_read.values())
                         cur_cmpt = set()
-                        for allele, count in Gene_count_per_read.items():
+                        for allele, count in list(Gene_count_per_read.items()):
                             if count < max_count:
                                 continue
                             if len(include_alleles) > 0 and allele not in include_alleles:
@@ -978,7 +978,7 @@
                             alleles = ["", ""]
                             allele1_found, allele2_found = False, False
                             if alleles[0] != "":
-                                for allele, count in Gene_count_per_read.items():
+                                for allele, count in list(Gene_count_per_read.items()):
                                     if count < max_count:
                                         continue
                                     if allele == alleles[0]:
@@ -986,12 +986,12 @@
                                     elif allele == alleles[1]:
                                         allele2_found = True
                                 if allele1_found != allele2_found:
-                                    print >> sys.stderr, alleles[0], Gene_count_per_read[alleles[0]]
-                                    print >> sys.stderr, alleles[1], Gene_count_per_read[alleles[1]]
+                                    print(alleles[0], Gene_count_per_read[alleles[0]], file=sys.stderr)
+                                    print(alleles[1], Gene_count_per_read[alleles[1]], file=sys.stderr)
                                     if allele1_found:
-                                        print >> sys.stderr, ("%s\tread_id %s - %d vs. %d]" % (alleles[0], prev_read_id, max_count, Gene_count_per_read[alleles[1]]))
+                                        print(("%s\tread_id %s - %d vs. %d]" % (alleles[0], prev_read_id, max_count, Gene_count_per_read[alleles[1]])), file=sys.stderr)
                                     else:
-                                        print >> sys.stderr, ("%s\tread_id %s - %d vs. %d]" % (alleles[1], prev_read_id, max_count, Gene_count_per_read[alleles[0]]))
+                                        print(("%s\tread_id %s - %d vs. %d]" % (alleles[1], prev_read_id, max_count, Gene_count_per_read[alleles[0]])), file=sys.stderr)
 
                         cur_cmpt = sorted(list(cur_cmpt))
                         cur_cmpt = '-'.join(cur_cmpt)
@@ -1012,7 +1012,7 @@
                                 exon_hts = get_exon_haplotypes(positive_ht, ref_exons)
 
                                 if prev_read_id == "aHSQ1008:175:C0JVFACXX:5:1109:17665:21583":
-                                    print "positive_ht:", positive_ht, "exon_hts:", exon_hts
+                                    print("positive_ht:", positive_ht, "exon_hts:", exon_hts)
                                     
                                 for exon_ht in exon_hts:
                                     add_count(Gene_count_per_read, exon_ht, 1)
@@ -1020,7 +1020,7 @@
 
                             # DK - debugging purposes
                             if prev_read_id.startswith("a30"):
-                                print Gene_gen_count_per_read
+                                print(Gene_gen_count_per_read)
 
                             # DK - debugging purposes
                             """
@@ -1070,9 +1070,9 @@
                                               (not partial and cur_cmpt_gen != "" and not set(cur_cmpt_gen) & set(test_Gene_names))
                                               
                                 if show_debug:
-                                    print "%s are chosen instead of %s" % (cur_cmpt if partial else cur_cmpt_gen, '-'.join(test_Gene_names))
+                                    print("%s are chosen instead of %s" % (cur_cmpt if partial else cur_cmpt_gen, '-'.join(test_Gene_names)))
                                     for prev_line in prev_lines:
-                                        print "\t", prev_line
+                                        print("\t", prev_line)
 
                             prev_lines = []
 
@@ -1144,10 +1144,10 @@
                     DK_debug = False
                     if orig_read_id.startswith("a30|R"):
                         DK_debug = True
-                        print line
-                        print cmp_list
-                        print "positive hts:", left_positive_hts, right_positive_hts
-                        print "cmp_list [%d, %d]" % (cmp_list_left, cmp_list_right)
+                        print(line)
+                        print(cmp_list)
+                        print("positive hts:", left_positive_hts, right_positive_hts)
+                        print("cmp_list [%d, %d]" % (cmp_list_left, cmp_list_right))
 
                     # Node
                     read_node_pos, read_node_seq, read_node_qual, read_node_var = -1, [], [], []
@@ -1231,7 +1231,7 @@
                     continue
 
                 for f_ in [sys.stderr, report_file]:
-                    print >> f_, "\t\t\t%d reads and %d pairs are aligned" % (num_reads, num_pairs)
+                    print("\t\t\t%d reads and %d pairs are aligned" % (num_reads, num_pairs), file=f_)
                 
             else:
                 assert index_type == "linear"
@@ -1286,7 +1286,7 @@
             if base_fname != "hla":
                 Gene_cmpt, Gene_counts = Gene_gen_cmpt, Gene_gen_counts
                 
-            Gene_counts = [[allele, count] for allele, count in Gene_counts.items()]
+            Gene_counts = [[allele, count] for allele, count in list(Gene_counts.items())]
             def Gene_count_cmp(a, b):
                 if a[1] != b[1]:
                     return b[1] - a[1]
@@ -1303,18 +1303,18 @@
                     for test_Gene_name in test_Gene_names:
                         if count[0] == test_Gene_name:
                             for f_ in [sys.stderr, report_file]:
-                                print >> f_, "\t\t\t*** %d ranked %s (count: %d)" % (count_i + 1, test_Gene_name, count[1])
+                                print("\t\t\t*** %d ranked %s (count: %d)" % (count_i + 1, test_Gene_name, count[1]), file=f_)
                             found = True
                     if count_i < 5 and not found:
                         for f_ in [sys.stderr, report_file]:
-                            print >> f_, "\t\t\t\t%d %s (count: %d)" % (count_i + 1, count[0], count[1])
+                            print("\t\t\t\t%d %s (count: %d)" % (count_i + 1, count[0], count[1]), file=f_)
                 else:
                     for f_ in [sys.stderr, report_file]:
-                        print >> f_, "\t\t\t\t%d %s (count: %d)" % (count_i + 1, count[0], count[1])
+                        print("\t\t\t\t%d %s (count: %d)" % (count_i + 1, count[0], count[1]), file=f_)
                     if count_i >= 9:
                         break
             for f_ in [sys.stderr, report_file]:
-                print >> f_
+                print(file=f_)
 
             # Calculate the abundance of representative alleles on exonic sequences
             if base_fname == "hla":
@@ -1337,7 +1337,7 @@
 
                 if len(gen_alleles) > 0:
                     Gene_gen_cmpt2 = {}
-                    for cmpt, value in Gene_gen_cmpt.items():
+                    for cmpt, value in list(Gene_gen_cmpt.items()):
                         cmpt2 = []
                         for allele in cmpt.split('-'):
                             if allele in gen_alleles:
@@ -1360,7 +1360,7 @@
                             Gene_combined_prob[allele] = prob
                     for allele, prob in Gene_gen_prob:
                         Gene_combined_prob[allele] = prob * gen_prob_sum
-                    Gene_prob = [[allele, prob] for allele, prob in Gene_combined_prob.items()]
+                    Gene_prob = [[allele, prob] for allele, prob in list(Gene_combined_prob.items())]
                     Gene_prob = sorted(Gene_prob, cmp=typing_common.Gene_prob_cmp)
             else:
                 Gene_prob = typing_common.single_abundance(Gene_cmpt, Gene_lengths[gene])
@@ -1403,7 +1403,7 @@
                 # Compare two alleles
                 if simulation and len(test_Gene_names) == 2:
                     allele_name1, allele_name2 = test_Gene_names
-                    print >> sys.stderr, allele_name1, "vs.", allele_name2
+                    print(allele_name1, "vs.", allele_name2, file=sys.stderr)
                     asm_graph.print_node_comparison(asm_graph.true_allele_nodes)
 
                 def compare_alleles(vars1, vars2, print_output = True):
@@ -1435,8 +1435,8 @@
                             skip = False
                             if print_output:
                                 if cmp_var_in_exon:
-                                    print >> sys.stderr, "\033[94mexon%d\033[00m" % (exon_i + 1),
-                                print >> sys.stderr, cmp_var_id, cmp_var, "\t\t\t", mpileup[cmp_var[1]]
+                                    print("\033[94mexon%d\033[00m" % (exon_i + 1), end=' ', file=sys.stderr)
+                                print(cmp_var_id, cmp_var, "\t\t\t", mpileup[cmp_var[1]], file=sys.stderr)
                             var_i += 1; var_j += 1
                             continue
                         if cmp_var[1] <= node_var[1]:
@@ -1445,42 +1445,42 @@
                                     if print_output:
                                         if cmp_var_in_exon:
                                             for f_ in [sys.stderr, report_file]:
-                                                print >> f_, "\033[94mexon%d\033[00m" % (exon_i + 1),
+                                                print("\033[94mexon%d\033[00m" % (exon_i + 1), end=' ', file=f_)
                                         for f_ in [sys.stderr, report_file]:
-                                            print >> f_, "***", cmp_var_id, cmp_var, "==", "\t\t\t", mpileup[cmp_var[1]]
+                                            print("***", cmp_var_id, cmp_var, "==", "\t\t\t", mpileup[cmp_var[1]], file=f_)
                                     mismatches += 1
                             var_i += 1
                         else:
                             if print_output:
                                 if node_var_in_exon:
                                     for f_ in [sys.stderr, report_file]:
-                                        print >> f_, "\033[94mexon%d\033[00m" % (exon_i + 1),
+                                        print("\033[94mexon%d\033[00m" % (exon_i + 1), end=' ', file=f_)
                                 for f_ in [sys.stderr, report_file]:
-                                    print >> f_, "*** ==", node_var_id, node_var, "\t\t\t", mpileup[node_var[1]]
+                                    print("*** ==", node_var_id, node_var, "\t\t\t", mpileup[node_var[1]], file=f_)
                             mismatches += 1
                             var_j += 1
                             
                     return mismatches
                     
                 tmp_nodes = asm_graph.nodes
-                print >> sys.stderr, "Number of tmp nodes:", len(tmp_nodes)
+                print("Number of tmp nodes:", len(tmp_nodes), file=sys.stderr)
                 count = 0
-                for id, node in tmp_nodes.items():
+                for id, node in list(tmp_nodes.items()):
                     count += 1
                     if count > 10:
                         break
                     node_vars = node.get_var_ids()
-                    node.print_info(); print >> sys.stderr
+                    node.print_info(); print(file=sys.stderr)
                     if node.id in asm_graph.to_node:
                         for id2, at in asm_graph.to_node[node.id]:
-                            print >> sys.stderr, "\tat %d ==> %s" % (at, id2)
+                            print("\tat %d ==> %s" % (at, id2), file=sys.stderr)
 
                     if simulation:
                         cmp_Gene_names = test_Gene_names
                     else:
                         cmp_Gene_names = [allele_name for allele_name, _ in allele_node_order]
                         
-                    alleles, cmp_vars, max_common = [], [], -sys.maxint
+                    alleles, cmp_vars, max_common = [], [], -sys.maxsize
                     for cmp_Gene_name in cmp_Gene_names:
                         tmp_vars = allele_nodes[cmp_Gene_name].get_var_ids(node.left, node.right)
                         tmp_common = len(set(node_vars) & set(tmp_vars))
@@ -1493,19 +1493,19 @@
 
                     for allele_name, cmp_vars in alleles:
                         for f_ in [sys.stderr, report_file]:
-                            print >> f_, "vs.", allele_name
+                            print("vs.", allele_name, file=f_)
                         compare_alleles(cmp_vars, node_vars)
 
-                    print >> sys.stderr
-                    print >> sys.stderr
+                    print(file=sys.stderr)
+                    print(file=sys.stderr)
 
 
             # Identify alleles that perfectly or closesly match assembled alleles
-            for node_name, node in asm_graph.nodes.items():
+            for node_name, node in list(asm_graph.nodes.items()):
                 vars = set(node.get_var_ids())
 
-                max_allele_names, max_common = [], -sys.maxint
-                for allele_name, vars2 in allele_vars.items():
+                max_allele_names, max_common = [], -sys.maxsize
+                for allele_name, vars2 in list(allele_vars.items()):
                     vars2 = set(vars2)
                     tmp_common = len(vars & vars2) - len(vars | vars2)
                     if tmp_common > max_common:
@@ -1515,21 +1515,21 @@
                         max_allele_names.append(allele_name)
 
                 for f_ in [sys.stderr, report_file]:
-                    print >> f_, "Genomic:", node_name
+                    print("Genomic:", node_name, file=f_)
                     node_vars = node.get_var_ids()
-                    min_mismatches = sys.maxint
+                    min_mismatches = sys.maxsize
                     for max_allele_name in max_allele_names:
                         cmp_vars = allele_vars[max_allele_name]
                         cmp_vars = sorted(cmp_vars, cmp=lambda a, b: int(a[2:]) - int(b[2:]))
                         print_output = False
                         tmp_mismatches = compare_alleles(cmp_vars, node_vars, print_output)
-                        print >> f_, "\t\t%s:" % max_allele_name, max_common, tmp_mismatches
+                        print("\t\t%s:" % max_allele_name, max_common, tmp_mismatches, file=f_)
                         if tmp_mismatches < min_mismatches:
                             min_mismatches = tmp_mismatches
                     if min_mismatches > 0:
-                        print >> f_, "Novel allele"
+                        print("Novel allele", file=f_)
                     else:
-                        print >> f_, "Known allele"
+                        print("Known allele", file=f_)
 
             """
             allele_exon_vars = {}
@@ -1581,7 +1581,7 @@
                                 else:
                                     break
                             for f_ in [sys.stderr, report_file]:
-                                print >> f_, "\t\t\t*** %d ranked %s (abundance: %.2f%%)" % (rank_i + 1, test_Gene_name, prob[1] * 100.0)
+                                print("\t\t\t*** %d ranked %s (abundance: %.2f%%)" % (rank_i + 1, test_Gene_name, prob[1] * 100.0), file=f_)
                             if rank_i < len(success):
                                 success[rank_i] = True
                             found_list[name_i] = True
@@ -1591,15 +1591,15 @@
                         break
                 if not found:
                     for f_ in [sys.stderr, report_file]:
-                        print >> f_, "\t\t\t\t%d ranked %s (abundance: %.2f%%)" % (prob_i + 1, _allele_rep, prob[1] * 100.0)
+                        print("\t\t\t\t%d ranked %s (abundance: %.2f%%)" % (prob_i + 1, _allele_rep, prob[1] * 100.0), file=f_)
                     if best_alleles and prob_i < 2:
                         for f_ in [sys.stderr, report_file]:
-                            print >> f_, "SingleModel %s (abundance: %.2f%%)" % (_allele_rep, prob[1] * 100.0)
+                            print("SingleModel %s (abundance: %.2f%%)" % (_allele_rep, prob[1] * 100.0), file=f_)
                 if not simulation and prob_i >= 9:
                     break
                 if prob_i >= 19:
                     break
-            print >> sys.stderr
+            print(file=sys.stderr)
 
             if simulation and not False in success:
                 aligner_type = "%s %s" % (aligner, index_type)
@@ -1646,7 +1646,7 @@
     for gene_name in Genes:
         # Assert there is only one allele per gene, which is a backbone allele
         assert len(Genes[gene_name]) == 1
-        backbone_allele_name, backbone_seq = Genes[gene_name].items()[0]
+        backbone_allele_name, backbone_seq = list(Genes[gene_name].items())[0]
         gene_vars, gene_var_list = Vars[gene_name], Var_list[gene_name]
         allele_vars = {}
         for _, var_id in gene_var_list:
@@ -1655,7 +1655,7 @@
                     allele_vars[allele_name] = []
                 allele_vars[allele_name].append(var_id)
 
-        for allele_name, vars in allele_vars.items():
+        for allele_name, vars in list(allele_vars.items()):
             seq = ""
             prev_pos = 0
             for var_id in vars:
@@ -1710,7 +1710,7 @@
         Vars[gene][var_id] = [var_type, pos, data]
         Var_list[gene].append([pos, var_id])
         
-    for gene, in_var_list in Var_list.items():
+    for gene, in_var_list in list(Var_list.items()):
         Var_list[gene] = sorted(in_var_list)
 
     return Vars, Var_list
@@ -1720,7 +1720,7 @@
 """
 def read_Gene_vars_genotype_genome(fname, refGene_loci):
     loci = {}
-    for gene, values in refGene_loci.items():
+    for gene, values in list(refGene_loci.items()):
         allele_name, chr, left, right = values[:4]
         if chr not in loci:
             loci[chr] = []
@@ -1750,7 +1750,7 @@
         Vars[gene][var_id] = [var_type, pos - left, data]
         Var_list[gene].append([pos - left, var_id])
         
-    for gene, in_var_list in Var_list.items():
+    for gene, in_var_list in list(Var_list.items()):
         Var_list[gene] = sorted(in_var_list)
 
     return Vars, Var_list
@@ -1847,7 +1847,7 @@
             genome_fnames.append(genotype_genome + ".%d.ht2" % (i+1))
 
         if not typing_common.check_files(genome_fnames):
-            print >> sys.stderr, "Error: some of the following files are not available:", ' '.join(genome_fnames)
+            print("Error: some of the following files are not available:", ' '.join(genome_fnames), file=sys.stderr)
             sys.exit(1)
     else:
         typing_common.extract_database_if_not_exists(base_fname,
@@ -1896,7 +1896,7 @@
         refGene_loci[Gene_gene] = [Gene_name, chr, left, right, exons]
     Genes = {}
     if len(locus_list) == 0:
-        locus_list = refGene_loci.keys()
+        locus_list = list(refGene_loci.keys())
 
     # Read HLA variants, and link information
     if genotype_genome:
@@ -1920,23 +1920,23 @@
         Genes2 = {}
         read_Gene_alleles(base_fname + "_backbone.fa", Genes2)
         read_Gene_alleles(base_fname + "_sequences.fa", Genes2)
-        for gene_name, alleles in Genes.items():
+        for gene_name, alleles in list(Genes.items()):
             assert gene_name in Genes2
-            for allele_name, allele_seq in alleles.items():
+            for allele_name, allele_seq in list(alleles.items()):
                 assert allele_name in Genes2[gene_name]
                 allele_seq2 = Genes2[gene_name][allele_name]
                 assert allele_seq == allele_seq2
 
     # HLA gene alleles
     Gene_names = {}
-    for Gene_gene, data in Genes.items():
+    for Gene_gene, data in list(Genes.items()):
         Gene_names[Gene_gene] = list(data.keys())
 
     # HLA gene allele lengths
     Gene_lengths = {}
-    for Gene_gene, Gene_alleles in Genes.items():
+    for Gene_gene, Gene_alleles in list(Genes.items()):
         Gene_lengths[Gene_gene] = {}
-        for allele_name, seq in Gene_alleles.items():
+        for allele_name, seq in list(Gene_alleles.items()):
             Gene_lengths[Gene_gene][allele_name] = len(seq)
 
     # Test HLA typing
@@ -1988,7 +1988,7 @@
                 if str(test_i + 1) not in test_ids:
                     continue
 
-            print >> sys.stderr, "Test %d" % (test_i + 1), str(datetime.now())
+            print("Test %d" % (test_i + 1), str(datetime.now()), file=sys.stderr)
             test_locus_list = test_list[test_i]
             num_frag_list = typing_common.simulate_reads(Genes,
                                                          base_fname,
@@ -2012,7 +2012,7 @@
                     gene = test_Gene_name.split('*')[0]
                     test_Gene_seq = Genes[gene][test_Gene_name]
                     seq_type = "partial" if test_Gene_name in partial_alleles else "full"
-                    print >> sys.stderr, "\t%s - %d bp (%s sequence, %d pairs)" % (test_Gene_name, len(test_Gene_seq), seq_type, num_frag_list_i[j_])
+                    print("\t%s - %d bp (%s sequence, %d pairs)" % (test_Gene_name, len(test_Gene_seq), seq_type, num_frag_list_i[j_]), file=sys.stderr)
 
             if "single-end" in debug_instr:
                 read_fname = ["%s_input_1.fa" % base_fname]
@@ -2051,20 +2051,20 @@
                                      best_alleles,
                                      verbose)
 
-            for aligner_type, passed in tmp_test_passed.items():
+            for aligner_type, passed in list(tmp_test_passed.items()):
                 if aligner_type in test_passed:
                     test_passed[aligner_type] += passed
                 else:
                     test_passed[aligner_type] = passed
 
-                print >> sys.stderr, "\t\tPassed so far: %d/%d (%.2f%%)" % (test_passed[aligner_type], test_i + 1, (test_passed[aligner_type] * 100.0 / (test_i + 1)))
+                print("\t\tPassed so far: %d/%d (%.2f%%)" % (test_passed[aligner_type], test_i + 1, (test_passed[aligner_type] * 100.0 / (test_i + 1))), file=sys.stderr)
 
 
-        for aligner_type, passed in test_passed.items():
-            print >> sys.stderr, "%s:\t%d/%d passed (%.2f%%)" % (aligner_type, passed, len(test_list), passed * 100.0 / len(test_list))
+        for aligner_type, passed in list(test_passed.items()):
+            print("%s:\t%d/%d passed (%.2f%%)" % (aligner_type, passed, len(test_list), passed * 100.0 / len(test_list)), file=sys.stderr)
     
     else: # With real reads or BAMs
-        print >> sys.stderr, "\t", ' '.join(locus_list)
+        print("\t", ' '.join(locus_list), file=sys.stderr)
         typing(simulation,
                base_fname,
                locus_list,
@@ -2251,7 +2251,7 @@
     else:
         locus_list = only_locus_list = args.only_locus_list.split(',')    
     if args.aligners == "":
-        print >> sys.stderr, "Error: --aligners must be non-empty."
+        print("Error: --aligners must be non-empty.", file=sys.stderr)
         sys.exit(1)    
     args.aligners = args.aligners.split(',')
     for i in range(len(args.aligners)):
@@ -2260,14 +2260,14 @@
         args.read_fname = [args.read_fname_U]
     elif args.read_fname_1 != "" or args.read_fname_2 != "":
         if args.read_fname_1 == "" or args.read_fname_2 == "":
-            print >> sys.stderr, "Error: please specify both -1 and -2."
+            print("Error: please specify both -1 and -2.", file=sys.stderr)
             sys.exit(1)
         args.read_fname = [args.read_fname_1, args.read_fname_2]
     else:
         args.read_fname = []
     if args.alignment_fname != "" and \
             not os.path.exists(args.alignment_fname):
-        print >> sys.stderr, "Error: %s doesn't exist." % args.alignment_fname
+        print("Error: %s doesn't exist." % args.alignment_fname, file=sys.stderr)
         sys.exit(1)
 
     if args.verbose and args.verbose_level == 0:
@@ -2285,10 +2285,10 @@
                 debug[item] = 1
 
     if not args.partial:
-        print >> sys.stderr, "Warning: --no-partial should be used for debugging purpose only."
+        print("Warning: --no-partial should be used for debugging purpose only.", file=sys.stderr)
 
     if args.read_len * 2 > args.fragment_len:
-        print >> sys.stderr, "Warning: fragment might be too short (%d)" % (args.fragment_len)
+        print("Warning: fragment might be too short (%d)" % (args.fragment_len), file=sys.stderr)
 
     skip_fragment_regions = []
     if args.skip_fragment_regions != "":
--- hisat2.orig/hisatgenotype_modules/hisatgenotype_assembly_graph.py
+++ hisat2/hisatgenotype_modules/hisatgenotype_assembly_graph.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 import sys
 import math, random
@@ -11,7 +11,7 @@
 def get_major_nt(nt_dic):
     nt = ''
     max_count = 0
-    for tmp_nt, tmp_value in nt_dic.items():
+    for tmp_nt, tmp_value in list(nt_dic.items()):
         tmp_count, tmp_var_id = tmp_value
         if len(tmp_nt) == 1:
             assert tmp_nt in "ACGTDN"
@@ -29,8 +29,8 @@
 
 #
 def match_score(nt_dic1, nt_dic2):
-    sum_1 = sum([count for count, _ in nt_dic1.values()])
-    sum_2 = sum([count for count, _ in nt_dic2.values()])
+    sum_1 = sum([count for count, _ in list(nt_dic1.values())])
+    sum_2 = sum([count for count, _ in list(nt_dic2.values())])
     total1, total2 = sum_1 * 2.0, sum_2 * 2.0
     best = 0.0
     for nt in "ACGT":
@@ -189,12 +189,12 @@
                     break
 
             if debug:
-                print "at %d (%d) with overlap of %d and mismatch of %.2f" % (i, self.left + i, j, tmp_mm)
+                print("at %d (%d) with overlap of %d and mismatch of %.2f" % (i, self.left + i, j, tmp_mm))
 
             if tmp_mm <= max_mm:
                 return i, min(len(seq) - i, len(other_seq)), tmp_mm
                 
-        return -1, -1, sys.maxint
+        return -1, -1, sys.maxsize
 
     
     # Combine two nodes with considering deletions
@@ -208,7 +208,7 @@
         assert self.left <= other.left
 
         # Merge two sequences
-        assert len(other.seq) > 0 and 'D' not in other.seq[0].keys()
+        assert len(other.seq) > 0 and 'D' not in list(other.seq[0].keys())
         j = 0        
         # Merge the overlapped parts
         if self.right >= other.left:
@@ -225,7 +225,7 @@
             new_seq = self.seq[:i]
             while i < len(self.seq) and j < len(other.seq):
                 nt_dic, nt_dic2 = self.seq[i], other.seq[j]
-                for nt, value in nt_dic2.items():
+                for nt, value in list(nt_dic2.items()):
                     count, var_id = value
                     if nt in nt_dic:
                         nt_dic[nt][0] += count
@@ -242,8 +242,8 @@
         # Fill in the gap between the two nodes if exists
         else:
             new_seq = self.seq[:]
-            sum_1 = sum([count for count, _ in self.seq[-1].values()])
-            sum_2 = sum([count for count, _ in other.seq[0].values()])
+            sum_1 = sum([count for count, _ in list(self.seq[-1].values())])
+            sum_2 = sum([count for count, _ in list(other.seq[0].values())])
             flank_cov = (sum_1 + sum_2) / 2.0
             for k in range(other.left - self.right - 1):
                 ref_nt_dic = self.mpileup[k + 1 + self.right][1]
@@ -252,8 +252,8 @@
                 if len(ref_nt_dic) == 0 or True:
                     nt_dic = {'N' : [1, ""]}
                 else:
-                    weight = flank_cov / max(1.0, sum([count for count, _ in ref_nt_dic.values()]))
-                    for nt, value in ref_nt_dic.items():
+                    weight = flank_cov / max(1.0, sum([count for count, _ in list(ref_nt_dic.values())]))
+                    for nt, value in list(ref_nt_dic.items()):
                         count, var_id = value
                         nt_dic[nt] = [count * weight, var_id]
                 new_seq.append(nt_dic)
@@ -293,7 +293,7 @@
 
     
     # Get variant ids
-    def get_var_ids(self, left = 0, right = sys.maxint):
+    def get_var_ids(self, left = 0, right = sys.maxsize):
         vars = []
         left = max(left, self.left)
         right = min(right, self.right)
@@ -308,7 +308,7 @@
                     ins_len += 1
                 else:
                     break            
-            for _, var in nt_dic.values():
+            for _, var in list(nt_dic.values()):
                 if var == "" or \
                    var == "unknown":
                     continue
@@ -326,7 +326,7 @@
     
     # Get variant ids
     #   left, right are absolute coordinates
-    def get_vars(self, left = 0, right = sys.maxint):
+    def get_vars(self, left = 0, right = sys.maxsize):
         vars = []
         left = max(left, self.left)
         right = min(right, self.right)
@@ -353,7 +353,7 @@
                 vars.append(["gap", pos])
                 continue            
             added = False
-            for _, var in nt_dic.values():
+            for _, var in list(nt_dic.values()):
                 if var == "" or \
                    var == "unknown":
                     continue
@@ -369,7 +369,7 @@
                         skip_pos = pos + int(data) - 1
                     added = True
                     vars.append([var, pos])
-            if not added and "unknown" in [var_id for _, var_id in nt_dic.values()]:
+            if not added and "unknown" in [var_id for _, var_id in list(nt_dic.values())]:
                 vars.append(["unknown", pos])
 
         return vars
@@ -384,7 +384,7 @@
     def calculate_avg_cov(self):
         self.avg = 0.0
         for nt_dic in self.seq:
-            for count, _ in nt_dic.values():
+            for count, _ in list(nt_dic.values()):
                 self.avg += count
         self.avg /= len(self.seq)
         return self.avg
@@ -418,7 +418,7 @@
                 seq += "\033[00m"
 
             var = []
-            for _, var_id in nt_dic.values():
+            for _, var_id in list(nt_dic.values()):
                 if var_id == "":
                     continue
                 var.append(var_id)
@@ -429,13 +429,13 @@
             if nt[0] == 'I':
                 ins_len += 1
         
-        print >> output, "Node ID:", self.id
-        print >> output, "Pos: [%d, %d], Avg. coverage: %.1f" % (self.left, self.right, self.get_avg_cov())
-        print >> output, "\t", seq
-        print >> output, "\t", var_str
-        print >> output, "mates:", len(self.mate_ids) # sorted(self.mate_ids)
-        print >> output, "reads:", len(self.read_ids) # sorted(self.read_ids)
-        print >> output
+        print("Node ID:", self.id, file=output)
+        print("Pos: [%d, %d], Avg. coverage: %.1f" % (self.left, self.right, self.get_avg_cov()), file=output)
+        print("\t", seq, file=output)
+        print("\t", var_str, file=output)
+        print("mates:", len(self.mate_ids), file=output) # sorted(self.mate_ids)
+        print("reads:", len(self.read_ids), file=output) # sorted(self.read_ids)
+        print(file=output)
 
                 
 class Graph:
@@ -484,7 +484,7 @@
         if simulation:
             id = id.split('_')[0]
         if id in self.nodes:
-            print >> sys.stderr, "Warning) multi-mapped read:", id
+            print("Warning) multi-mapped read:", id, file=sys.stderr)
             # assert False
             return
         assert id not in self.nodes
@@ -494,7 +494,7 @@
     # Remove nodes that are inside other nodes or with low coverage
     def remove_nodes(self, nodes):
         delete_ids = set()
-        node_list = [[id, node.left, node.right] for id, node in nodes.items()]
+        node_list = [[id, node.left, node.right] for id, node in list(nodes.items())]
         def node_cmp(a, b):
             if a[2] != b[2]:
                 return a[2] - b[2]
@@ -547,7 +547,7 @@
         CP_IMPL = True
 
         node_seq = {}
-        for id, node in self.nodes.items():
+        for id, node in list(self.nodes.items()):
             s, seq = 0, []
             while s < len(node.seq):
                 nt_dic = node.seq[s] # {'C': [1, '']}
@@ -605,7 +605,7 @@
         while True:
             delete_ids = set()
             nodes = []
-            for id, node in self.nodes.items():
+            for id, node in list(self.nodes.items()):
                 seq = node_seq[id]
                 if len(seq) < k:
                     continue
@@ -710,8 +710,8 @@
                 # DK - debugging purposes
                 debug_msg = False
                 if debug_msg:
-                    print >> sys.stderr, "at", pos, vertices
-                    print >> sys.stderr, "count:", vertice_count
+                    print("at", pos, vertices, file=sys.stderr)
+                    print("count:", vertice_count, file=sys.stderr)
 
                 if try_hard:
                     vertice_with_id = [[vertice_count[v], v] for v in range(len(vertice_count))]
@@ -721,7 +721,7 @@
                         num_ids = vertices[v][3]
                         delete_ids |= set(num_ids)
                         if debug_msg:
-                            print >> sys.stderr, v, "is removed with", num_ids
+                            print(v, "is removed with", num_ids, file=sys.stderr)
                 else:
                     for v in range(len(vertices)):
                         assert len(vertices) >= 2
@@ -753,7 +753,7 @@
                                     num_ids = vertices[v][3]
                                     delete_ids |= set(num_ids)
                                     if debug_msg:
-                                        print >> sys.stderr, v, "is removed with", num_ids
+                                        print(v, "is removed with", num_ids, file=sys.stderr)
                                 elif vertice_count[v] * 8 < avg_kmers:
                                     num_ids = vertices[v][3]
                                     delete_ids |= set(num_ids)
@@ -762,11 +762,11 @@
                                 num_ids = vertices[v][3]
                                 delete_ids |= set(num_ids)
                                 if debug_msg:
-                                    print >> sys.stderr, v, "is removed with", num_ids
+                                    print(v, "is removed with", num_ids, file=sys.stderr)
 
                 if debug_msg:
-                    print >> sys.stderr
-                    print >> sys.stderr             
+                    print(file=sys.stderr)
+                    print(file=sys.stderr)             
                 
             if len(delete_ids) == 0:
                 if try_hard:
@@ -797,7 +797,7 @@
                     else:
                         consensus_seq[j][nt] += 1
 
-            if print_msg: print >> sys.stderr, i
+            if print_msg: print(i, file=sys.stderr)
             for v in range(len(curr_vertices)):
                 nt, k_m1_mer, predecessors, num_ids = curr_vertices[v]
                 kmer = k_m1_mer + nt
@@ -810,7 +810,7 @@
                     if len(consensus_seq[j]) >= 2:
                         kmer_seq += "\033[00m"
                     
-                if print_msg: print >> sys.stderr, "\t%d:" % v, kmer_seq, len(num_ids), predecessors, num_ids
+                if print_msg: print("\t%d:" % v, kmer_seq, len(num_ids), predecessors, num_ids, file=sys.stderr)
                     
 
         # """
@@ -903,7 +903,7 @@
 
         # DK - debugging purposes
         for p in range(len(paths)):
-            if print_msg: print >> sys.stderr, "path:", p, paths[p]
+            if print_msg: print("path:", p, paths[p], file=sys.stderr)
 
         excl_num_ids = set() # exclusive num ids
         equiv_list = []
@@ -949,9 +949,9 @@
                 classes = equiv_list[i]
                 for j in range(len(classes)):
                     ids, num_ids, all_ids, alleles = classes[j]
-                    if print_msg: print >> sys.stderr, i, j, ids, len(num_ids), sorted(list(num_ids))[:20], alleles
+                    if print_msg: print(i, j, ids, len(num_ids), sorted(list(num_ids))[:20], alleles, file=sys.stderr)
 
-                if print_msg: print >> sys.stderr
+                if print_msg: print(file=sys.stderr)
             # """
 
             if known_alleles:
@@ -962,8 +962,8 @@
                         node_id = "(%d-%d)%s" % (i, j, num_to_id[num_ids[0]])
                         node = self.nodes2[node_id]
                         node_vars = node.get_var_ids()
-                        max_alleles, max_common = set(), -sys.maxint
-                        for anode in self.predicted_allele_nodes.values():
+                        max_alleles, max_common = set(), -sys.maxsize
+                        for anode in list(self.predicted_allele_nodes.values()):
                             allele_vars = anode.get_var_ids(node.left, node.right)
                             tmp_common = len(set(node_vars) & set(allele_vars)) - len(set(node_vars) | set(allele_vars))
                             if tmp_common > max_common:
@@ -974,7 +974,7 @@
                         classes[j][3] = max_alleles
 
             
-            best_common_mat, best_stat, best_i, best_i2 = [], -sys.maxint, -1, -1
+            best_common_mat, best_stat, best_i, best_i2 = [], -sys.maxsize, -1, -1
             for i in range(len(equiv_list) - 1):
                 classes = equiv_list[i]
                 for i2 in range(i + 1, len(equiv_list)):
@@ -1012,9 +1012,9 @@
             # DK - debugging purposes
             # """
             if print_msg:
-                print >> sys.stderr, "best:", best_i, best_i2, best_stat, best_common_mat
-                print >> sys.stderr
-                print >> sys.stderr
+                print("best:", best_i, best_i2, best_stat, best_common_mat, file=sys.stderr)
+                print(file=sys.stderr)
+                print(file=sys.stderr)
             # """
 
             if known_alleles and best_stat < 0:
@@ -1030,7 +1030,7 @@
                         num_ids = sorted(list(num_ids))
 
                         # DK - debugging purposes
-                        if print_msg: print >> sys.stderr, i, j, num_ids
+                        if print_msg: print(i, j, num_ids, file=sys.stderr)
 
                         assert (num_ids) > 0
                         read_id = num_to_id[num_ids[0]]
@@ -1208,7 +1208,7 @@
 
                 exclude_ids |= set(remove_list)
 
-                for node_id, node in self.nodes2.items():
+                for node_id, node in list(self.nodes2.items()):
                     if node_id in exclude_ids:
                         continue
                     num, id = node_id.split(')')
@@ -1228,14 +1228,14 @@
         
     # Display graph information
     def print_info(self): 
-        print >> sys.stderr, "Backbone len: %d" % len(self.backbone)
-        print >> sys.stderr, "\t%s" % self.backbone   
+        print("Backbone len: %d" % len(self.backbone), file=sys.stderr)
+        print("\t%s" % self.backbone, file=sys.stderr)   
 
 
     # Compare nodes and get information
     def get_node_comparison_info(self, node_dic):
         assert len(node_dic) > 0
-        nodes = [[id, node.left, node.right] for id, node in node_dic.items()]
+        nodes = [[id, node.left, node.right] for id, node in list(node_dic.items())]
         def node_cmp(a, b):
             if a[1] != b[1]:
                 return a[1] - b[1]
@@ -1322,15 +1322,15 @@
             if len(cur_seqs) <= 0:
                 continue
                 
-            print >> sys.stderr, p
+            print(p, file=sys.stderr)
             for seq, id in cur_seqs:
-                print >> sys.stderr, "\t", seq, id
+                print("\t", seq, id, file=sys.stderr)
                                 
         
     # Begin drawing graph
     def begin_draw(self, fname_base):
         assert len(self.nodes) > 0
-        nodes = [[id, node.left, node.right] for id, node in self.nodes.items()]
+        nodes = [[id, node.left, node.right] for id, node in list(self.nodes.items())]
         def node_cmp(a, b):
             return a[1] - b[1]
         nodes = sorted(nodes, cmp=node_cmp)
@@ -1355,26 +1355,26 @@
         js_file = htmlDraw.js_file
 
         # Choose font
-        print >> js_file, r'ctx.font = "12px Times New Roman";'
+        print(r'ctx.font = "12px Times New Roman";', file=js_file)
 
         # Draw vertical dotted lines at every 100nt and thick lines at every 500nt
-        print >> js_file, r'ctx.fillStyle = "gray";'
+        print(r'ctx.fillStyle = "gray";', file=js_file)
         for pos in range(0, nodes[-1][2], 100):
             if pos != 0 and pos % 500 == 0:
-                print >> js_file, r'ctx.setLineDash([]);'
-                print >> js_file, r'ctx.lineWidth = 1;'
+                print(r'ctx.setLineDash([]);', file=js_file)
+                print(r'ctx.lineWidth = 1;', file=js_file)
             else:
-                print >> js_file, r'ctx.setLineDash([5, 15]);'
-                print >> js_file, r'ctx.lineWidth = 0.2;'
+                print(r'ctx.setLineDash([5, 15]);', file=js_file)
+                print(r'ctx.lineWidth = 0.2;', file=js_file)
 
-            print >> js_file, r'ctx.beginPath();'
-            print >> js_file, r'ctx.moveTo(%d, %d);' % \
-                (get_x(pos), self.top_margin)
-            print >> js_file, r'ctx.lineTo(%d, %d);' % \
-                (get_x(pos), self.height)
-            print >> js_file, r'ctx.stroke();'
+            print(r'ctx.beginPath();', file=js_file)
+            print(r'ctx.moveTo(%d, %d);' % \
+                (get_x(pos), self.top_margin), file=js_file)
+            print(r'ctx.lineTo(%d, %d);' % \
+                (get_x(pos), self.height), file=js_file)
+            print(r'ctx.stroke();', file=js_file)
 
-        print >> js_file, r'ctx.setLineDash([]);'
+        print(r'ctx.setLineDash([]);', file=js_file)
 
 
     # End drawing graph
@@ -1388,7 +1388,7 @@
              begin_y,
              title = ""):
         assert len(self.nodes) > 0
-        nodes = [[id, node.left, node.right] for id, node in self.nodes.items()]
+        nodes = [[id, node.left, node.right] for id, node in list(self.nodes.items())]
         def node_cmp(a, b):
             return a[1] - b[1]
         nodes = sorted(nodes, cmp=node_cmp)
@@ -1462,26 +1462,26 @@
             right += 1
 
             # Draw node
-            print >> js_file, r'ctx.beginPath();'
-            print >> js_file, r'ctx.rect(%d, %d, %d, %d);' % \
-                (get_x(left), get_y(y), get_x(right) - get_x(left), get_sy(10))
-            print >> js_file, r'ctx.fillStyle = "white";'
-            print >> js_file, r'ctx.fill();'
-            print >> js_file, r'ctx.lineWidth = 2;'
-            print >> js_file, r'ctx.strokeStyle = "black";'
-            print >> js_file, r'ctx.stroke();'
+            print(r'ctx.beginPath();', file=js_file)
+            print(r'ctx.rect(%d, %d, %d, %d);' % \
+                (get_x(left), get_y(y), get_x(right) - get_x(left), get_sy(10)), file=js_file)
+            print(r'ctx.fillStyle = "white";', file=js_file)
+            print(r'ctx.fill();', file=js_file)
+            print(r'ctx.lineWidth = 2;', file=js_file)
+            print(r'ctx.strokeStyle = "black";', file=js_file)
+            print(r'ctx.stroke();', file=js_file)
 
             # Draw label
-            print >> js_file, r'ctx.fillStyle = "blue";'
-            print >> js_file, r'ctx.fillText("Exon %d", %d, %d);' % \
-                (e+1, get_x(left + 2), get_y(y + 7))
+            print(r'ctx.fillStyle = "blue";', file=js_file)
+            print(r'ctx.fillText("Exon %d", %d, %d);' % \
+                (e+1, get_x(left + 2), get_y(y + 7)), file=js_file)
 
             if e > 0:
                 prev_right = self.exons[e-1][1] + 1
-                print >> js_file, r'ctx.beginPath();'
-                print >> js_file, r'ctx.moveTo(%d, %d);' % (get_x(left), get_y(y + 5))
-                print >> js_file, r'ctx.lineTo(%d, %d);' % (get_x(prev_right), get_y(y + 5))
-                print >> js_file, r'ctx.stroke();'
+                print(r'ctx.beginPath();', file=js_file)
+                print(r'ctx.moveTo(%d, %d);' % (get_x(left), get_y(y + 5)), file=js_file)
+                print(r'ctx.lineTo(%d, %d);' % (get_x(prev_right), get_y(y + 5)), file=js_file)
+                print(r'ctx.stroke();', file=js_file)
 
         # Draw true or predicted alleles
         node_colors = ["#FFFF00", "#00FF00", "#FFCBA4", "#C14581"]
@@ -1518,27 +1518,27 @@
                         allele_type = "true"
                     else:
                         allele_type = "predicted"
-                print >> js_file, r'ctx.fillStyle = "blue";'
-                print >> js_file, r'ctx.font = "20px Times New Roman";'
-                print >> js_file, r'ctx.fillText("%s (%s, %s%s)", %d, %d);' % \
+                print(r'ctx.fillStyle = "blue";', file=js_file)
+                print(r'ctx.font = "20px Times New Roman";', file=js_file)
+                print(r'ctx.fillText("%s (%s, %s%s)", %d, %d);' % \
                     (allele_id,
                      "partial" if allele_id in self.partial_allele_ids else "full",
                      allele_type,
                      # prob,
                      "",
                      10,
-                     get_y(y + 5))
-                print >> js_file, r'ctx.font = "12px Times New Roman";'
+                     get_y(y + 5)), file=js_file)
+                print(r'ctx.font = "12px Times New Roman";', file=js_file)
         
                 # Draw node
-                print >> js_file, r'ctx.beginPath();'
-                print >> js_file, r'ctx.rect(%d, %d, %d, %d);' % \
-                    (get_x(left), get_y(y), get_x(right) - get_x(left), get_sy(10))
-                print >> js_file, r'ctx.fillStyle = "%s";' % (allele_node_colors[n % len(allele_node_colors)])
-                print >> js_file, r'ctx.fill();'
-                print >> js_file, r'ctx.lineWidth = 2;'
-                print >> js_file, r'ctx.strokeStyle = "black";'
-                print >> js_file, r'ctx.stroke();'
+                print(r'ctx.beginPath();', file=js_file)
+                print(r'ctx.rect(%d, %d, %d, %d);' % \
+                    (get_x(left), get_y(y), get_x(right) - get_x(left), get_sy(10)), file=js_file)
+                print(r'ctx.fillStyle = "%s";' % (allele_node_colors[n % len(allele_node_colors)]), file=js_file)
+                print(r'ctx.fill();', file=js_file)
+                print(r'ctx.lineWidth = 2;', file=js_file)
+                print(r'ctx.strokeStyle = "black";', file=js_file)
+                print(r'ctx.stroke();', file=js_file)
 
                 color_boxes = []
                 c = 0
@@ -1564,11 +1564,11 @@
                         color = "#1E90FF"
                     # DK - debugging purposes
                     color = "blue"
-                    print >> js_file, r'ctx.beginPath();'
-                    print >> js_file, r'ctx.rect(%d, %d, %d, %d);' % \
-                        (get_x(cleft), get_y(y + 1), get_x(cright) - get_x(cleft), get_sy(8))
-                    print >> js_file, r'ctx.fillStyle = "%s";' % (color)
-                    print >> js_file, r'ctx.fill();'
+                    print(r'ctx.beginPath();', file=js_file)
+                    print(r'ctx.rect(%d, %d, %d, %d);' % \
+                        (get_x(cleft), get_y(y + 1), get_x(cright) - get_x(cleft), get_sy(8)), file=js_file)
+                    print(r'ctx.fillStyle = "%s";' % (color), file=js_file)
+                    print(r'ctx.fill();', file=js_file)
             return allele_nodes, seqs, colors
 
         allele_nodes, seqs, colors = draw_alleles(self.true_allele_nodes if self.simulation else self.predicted_allele_nodes,
@@ -1581,9 +1581,9 @@
         y = get_dspace(0, nodes[-1][2], 14)
         for pos in range(0, nodes[-1][2], 100):
             # Draw label
-            print >> js_file, r'ctx.fillStyle = "blue";'
-            print >> js_file, r'ctx.fillText("%d", %d, %d);' % \
-                (pos, get_x(pos+2), get_y(y + 2))
+            print(r'ctx.fillStyle = "blue";', file=js_file)
+            print(r'ctx.fillText("%d", %d, %d);' % \
+                (pos, get_x(pos+2), get_y(y + 2)), file=js_file)
 
         # Draw nodes
         node_to_y = {}
@@ -1601,7 +1601,7 @@
             node_var_ids = node.get_var_ids()
             if len(allele_nodes) > 0:
                 color = "white"
-                max_common = -sys.maxint
+                max_common = -sys.maxsize
                 for a in range(len(allele_nodes)):
                     allele_node_id, allele_left, allele_right = allele_nodes[a]
                     if right - left <= 500 and (left < allele_left or right > allele_right):
@@ -1623,14 +1623,14 @@
 
             # Draw node
             right += 1
-            print >> js_file, r'ctx.beginPath();'
-            print >> js_file, r'ctx.rect(%d, %d, %d, %d);' % \
-                (get_x(left), get_y(y), get_x(right) - get_x(left), get_sy(10))
-            print >> js_file, r'ctx.fillStyle = "%s";' % color
-            print >> js_file, r'ctx.fill();'
-            print >> js_file, r'ctx.lineWidth = 2;'
-            print >> js_file, r'ctx.strokeStyle = "black";'
-            print >> js_file, r'ctx.stroke();'
+            print(r'ctx.beginPath();', file=js_file)
+            print(r'ctx.rect(%d, %d, %d, %d);' % \
+                (get_x(left), get_y(y), get_x(right) - get_x(left), get_sy(10)), file=js_file)
+            print(r'ctx.fillStyle = "%s";' % color, file=js_file)
+            print(r'ctx.fill();', file=js_file)
+            print(r'ctx.lineWidth = 2;', file=js_file)
+            print(r'ctx.strokeStyle = "black";', file=js_file)
+            print(r'ctx.stroke();', file=js_file)
 
             # Draw variants
             for var_id, pos in node_vars:
@@ -1648,35 +1648,35 @@
                 else:
                     assert var_type == "deletion"
                     var_right = var_left + int(var_data)
-                print >> js_file, r'ctx.beginPath();'
-                print >> js_file, r'ctx.rect(%d, %d, %d, %d);' % \
-                    (get_x(var_left), get_y(y + 1), get_x(var_right) - get_x(var_left), get_sy(8))
-                print >> js_file, r'ctx.fillStyle = "%s";' % (color)
-                print >> js_file, r'ctx.fill();'
+                print(r'ctx.beginPath();', file=js_file)
+                print(r'ctx.rect(%d, %d, %d, %d);' % \
+                    (get_x(var_left), get_y(y + 1), get_x(var_right) - get_x(var_left), get_sy(8)), file=js_file)
+                print(r'ctx.fillStyle = "%s";' % (color), file=js_file)
+                print(r'ctx.fill();', file=js_file)
 
             # Draw label
             if get_sx(right - left) >= 300:
-                print >> js_file, r'ctx.fillStyle = "blue";'
-                print >> js_file, r'ctx.fillText("%s", %d, %d);' % \
-                    (node.id, get_x(left + 2), get_y(y + 7))
+                print(r'ctx.fillStyle = "blue";', file=js_file)
+                print(r'ctx.fillText("%s", %d, %d);' % \
+                    (node.id, get_x(left + 2), get_y(y + 7)), file=js_file)
 
             if not draw_title:
                 draw_title = True
-                print >> js_file, r'ctx.font = "24px Times New Roman";'
-                print >> js_file, r'ctx.fillText("%s", %d, %d);' % \
-                    (title, 10, get_y(y + 7))
-                print >> js_file, r'ctx.font = "12px Times New Roman";'
+                print(r'ctx.font = "24px Times New Roman";', file=js_file)
+                print(r'ctx.fillText("%s", %d, %d);' % \
+                    (title, 10, get_y(y + 7)), file=js_file)
+                print(r'ctx.font = "12px Times New Roman";', file=js_file)
 
 
         # Draw edges
-        print >> js_file, r'ctx.lineWidth = 1;'
+        print(r'ctx.lineWidth = 1;', file=js_file)
         line_colors = ["red", "black", "blue"]
-        for node_id, to_node_ids in self.to_node.items():
+        for node_id, to_node_ids in list(self.to_node.items()):
             node = self.nodes[node_id]
             node_x = (get_x(node.left) + get_x(node.right)) / 2
             node_y = get_y(node_to_y[node_id] + 5)
-            print >> js_file, r'ctx.strokeStyle = "%s";' % \
-                line_colors[random.randrange(len(line_colors))]
+            print(r'ctx.strokeStyle = "%s";' % \
+                line_colors[random.randrange(len(line_colors))], file=js_file)
             for to_node_id, _ in to_node_ids:
                 to_node = self.nodes[to_node_id]
                 to_node_x = (get_x(to_node.left) + get_x(to_node.right) + (random.random() * 10 - 5)) / 2
@@ -1685,10 +1685,10 @@
                 jitter1, jitter2 = (random.random() * 10 - 5), (random.random() * 10 - 5)
                 jitter1, jitter2 = get_sx(jitter1), get_sx(jitter2)
 
-                print >> js_file, r'ctx.beginPath();'
-                print >> js_file, r'ctx.moveTo(%d, %d);' % (node_x + jitter1, node_y)
-                print >> js_file, r'ctx.lineTo(%d, %d);' % (to_node_x + jitter2, to_node_y)
-                print >> js_file, r'ctx.stroke();'
+                print(r'ctx.beginPath();', file=js_file)
+                print(r'ctx.moveTo(%d, %d);' % (node_x + jitter1, node_y), file=js_file)
+                print(r'ctx.lineTo(%d, %d);' % (to_node_x + jitter2, to_node_y), file=js_file)
+                print(r'ctx.stroke();', file=js_file)
 
         curr_y = get_dspace(0, nodes[-1][2], 1)
         return curr_y if curr_y > 0 else end_y
@@ -1702,32 +1702,32 @@
     def write_html_css(self, width = 2000, height = 1000):
         base_fname = self.base_fname
         html_file = open("%s.html" % base_fname, 'w')
-        print >> html_file, r'<!DOCTYPE html>'
-        print >> html_file, r'<html>'
-        print >> html_file, r'<head>'
-        print >> html_file, r'<title>HISAT-genotyping HLA</title>'
-        print >> html_file, r'<link rel="stylesheet" type="text/css" href="%s.css"/>' % (base_fname.split("/")[-1])
-        print >> html_file, r'</head>'
-        print >> html_file, r'<body>'
-        print >> html_file, r'<canvas id="a" width="%d" height="%d">' % (width, height)
-        print >> html_file, r'This text is displayed if your browser does not support HTML5 Canvas.'
-        print >> html_file, r'</canvas>'
-        print >> html_file, r'<script type="text/javascript" src="%s.js"></script>' % (base_fname.split("/")[-1])
-        print >> html_file, r'</body>'
-        print >> html_file, r'</html>'
+        print(r'<!DOCTYPE html>', file=html_file)
+        print(r'<html>', file=html_file)
+        print(r'<head>', file=html_file)
+        print(r'<title>HISAT-genotyping HLA</title>', file=html_file)
+        print(r'<link rel="stylesheet" type="text/css" href="%s.css"/>' % (base_fname.split("/")[-1]), file=html_file)
+        print(r'</head>', file=html_file)
+        print(r'<body>', file=html_file)
+        print(r'<canvas id="a" width="%d" height="%d">' % (width, height), file=html_file)
+        print(r'This text is displayed if your browser does not support HTML5 Canvas.', file=html_file)
+        print(r'</canvas>', file=html_file)
+        print(r'<script type="text/javascript" src="%s.js"></script>' % (base_fname.split("/")[-1]), file=html_file)
+        print(r'</body>', file=html_file)
+        print(r'</html>', file=html_file)
         html_file.close()
 
         css_file = open("%s.css" % base_fname, 'w')
-        print >> css_file, r'canvas {'
-        print >> css_file, r'border: 1px dotted black;'
-        print >> css_file, r'}'
+        print(r'canvas {', file=css_file)
+        print(r'border: 1px dotted black;', file=css_file)
+        print(r'}', file=css_file)
         css_file.close()
 
         
     def start_js(self):
         self.js_file = open("%s.js" % self.base_fname, 'w')
-        print >> self.js_file, r'var a_canvas = document.getElementById("a");'
-        print >> self.js_file, r'var ctx = a_canvas.getContext("2d");'
+        print(r'var a_canvas = document.getElementById("a");', file=self.js_file)
+        print(r'var ctx = a_canvas.getContext("2d");', file=self.js_file)
 
         
     def end_js(self):
@@ -1738,34 +1738,34 @@
         js_file = self.js_file
         
         # Draw the face
-        print >> js_file, r'ctx.fillStyle = "yellow";'
-        print >> js_file, r'ctx.beginPath();'
-        print >> js_file, r'ctx.arc(95, 85, 40, 0, 2*Math.PI);'
-        print >> js_file, r'ctx.closePath();'
-        print >> js_file, r'ctx.fill();'
-        print >> js_file, r'ctx.lineWidth = 2;'
-        print >> js_file, r'ctx.stroke();'
-        print >> js_file, r'ctx.fillStyle = "black";'
+        print(r'ctx.fillStyle = "yellow";', file=js_file)
+        print(r'ctx.beginPath();', file=js_file)
+        print(r'ctx.arc(95, 85, 40, 0, 2*Math.PI);', file=js_file)
+        print(r'ctx.closePath();', file=js_file)
+        print(r'ctx.fill();', file=js_file)
+        print(r'ctx.lineWidth = 2;', file=js_file)
+        print(r'ctx.stroke();', file=js_file)
+        print(r'ctx.fillStyle = "black";', file=js_file)
         
         # Draw the left eye
-        print >> js_file, r'ctx.beginPath();'
-        print >> js_file, r'ctx.arc(75, 75, 5, 0, 2*Math.PI);'
-        print >> js_file, r'ctx.closePath();'
-        print >> js_file, r'ctx.fill();'
+        print(r'ctx.beginPath();', file=js_file)
+        print(r'ctx.arc(75, 75, 5, 0, 2*Math.PI);', file=js_file)
+        print(r'ctx.closePath();', file=js_file)
+        print(r'ctx.fill();', file=js_file)
 
         # Draw the right eye
-        print >> js_file, r'ctx.beginPath();'
-        print >> js_file, r'ctx.arc(114, 75, 5, 0, 2*Math.PI);'
-        print >> js_file, r'ctx.closePath();'
-        print >> js_file, r'ctx.fill();'
+        print(r'ctx.beginPath();', file=js_file)
+        print(r'ctx.arc(114, 75, 5, 0, 2*Math.PI);', file=js_file)
+        print(r'ctx.closePath();', file=js_file)
+        print(r'ctx.fill();', file=js_file)
 
         # Draw the mouth
-        print >> js_file, r'ctx.beginPath();'
-        print >> js_file, r'ctx.arc(95, 90, 26, Math.PI, 2*Math.PI, true);'
-        print >> js_file, r'ctx.closePath();'
-        print >> js_file, r'ctx.fill();'
+        print(r'ctx.beginPath();', file=js_file)
+        print(r'ctx.arc(95, 90, 26, Math.PI, 2*Math.PI, true);', file=js_file)
+        print(r'ctx.closePath();', file=js_file)
+        print(r'ctx.fill();', file=js_file)
 
         # Write "Hello, World!"
-        print >> js_file, r'ctx.font = "30px Garamond";'
-        print >> js_file, r'ctx.fillText("Hello, World!", 15, 175);'
+        print(r'ctx.font = "30px Garamond";', file=js_file)
+        print(r'ctx.fillText("Hello, World!", 15, 175);', file=js_file)
        
--- hisat2.orig/hisatgenotype_modules/hisatgenotype_convert_codis.py
+++ hisat2/hisatgenotype_modules/hisatgenotype_convert_codis.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2017, Daehwan Kim <infphilo@gmail.com>
@@ -379,22 +379,22 @@
     CODIS_seq = orig_CODIS_seq
     if len(locus_list) > 0:
         new_CODIS_seq = {}
-        for locus_name, fields in CODIS_seq.items():
+        for locus_name, fields in list(CODIS_seq.items()):
             if locus_name in locus_list:
                 new_CODIS_seq[locus_name] = fields
         CODIS_seq = new_CODIS_seq        
 
     # Add some additional sequences to allele sequences to make them reasonably long for typing and assembly
-    for locus_name, fields in CODIS_seq.items():
+    for locus_name, fields in list(CODIS_seq.items()):
         _, left_seq, repeat_seq, right_seq = fields
         allele_seq = left_seq + repeat_seq + right_seq
         left_flank_seq, right_flank_seq = get_flanking_seqs(allele_seq)
         CODIS_seq[locus_name][1] = left_flank_seq + left_seq
         CODIS_seq[locus_name][3] = right_seq + right_flank_seq
 
-        print >> sys.stderr, "%s is found on the reference genome (GRCh38)" % locus_name
+        print("%s is found on the reference genome (GRCh38)" % locus_name, file=sys.stderr)
     
-    for locus_name in CODIS_seq.keys():
+    for locus_name in list(CODIS_seq.keys()):
         alleles = []
         for line in open("hisatgenotype_db/CODIS/codis.dat"):
             locus_name2, allele_id, repeat_st = line.strip().split('\t')
@@ -478,8 +478,8 @@
             for allele_id, repeat_st in alleles:
                 allele_seq = to_sequence(repeat_st)
                 if allele_seq in seq_to_ids:
-                    print >> sys.stderr, "Warning) %s: %s has the same sequence as %s" % \
-                        (locus_name, allele_id, seq_to_ids[allele_seq])
+                    print("Warning) %s: %s has the same sequence as %s" % \
+                        (locus_name, allele_id, seq_to_ids[allele_seq]), file=sys.stderr)
                     continue
                 if allele_seq not in seq_to_ids:
                     seq_to_ids[allele_seq] = [allele_id]
@@ -507,28 +507,28 @@
             allele_seqs = [[allele_id, ref_allele]] + allele_seqs
             alleles = [[allele_id, ref_allele_st]] + alleles
 
-        print >> sys.stderr, "%s: %d alleles with reference allele as %s" % (locus_name, len(alleles), CODIS_ref_name[locus_name])
+        print("%s: %d alleles with reference allele as %s" % (locus_name, len(alleles), CODIS_ref_name[locus_name]), file=sys.stderr)
         if verbose:
-            print >> sys.stderr, "\t", ref_allele_left, ref_allele, ref_allele_right
+            print("\t", ref_allele_left, ref_allele, ref_allele_right, file=sys.stderr)
             for allele_id, allele in alleles:
-                print >> sys.stderr, allele_id, "\t", allele
+                print(allele_id, "\t", allele, file=sys.stderr)
 
         # Create a backbone sequence
         assert len(alleles) > 0
         backbone_allele = deepcopy(alleles[-1][1])
         for allele_id, allele_st in reversed(alleles[:-1]):
             if verbose:
-                print >> sys.stderr
-                print >> sys.stderr, allele_id
-                print >> sys.stderr, "backbone         :", backbone_allele
-                print >> sys.stderr, "allele           :", allele_st
+                print(file=sys.stderr)
+                print(allele_id, file=sys.stderr)
+                print("backbone         :", backbone_allele, file=sys.stderr)
+                print("allele           :", allele_st, file=sys.stderr)
             backbone_allele = combine_alleles(backbone_allele, allele_st)
             msf_allele_seq, msf_backbone_seq = msf_alignment(backbone_allele, allele_st)
             if verbose:                
-                print >> sys.stderr, "combined backbone:", backbone_allele
-                print >> sys.stderr, "msf_allele_seq  :", msf_allele_seq
-                print >> sys.stderr, "msf_backbone_seq:", msf_backbone_seq
-                print >> sys.stderr
+                print("combined backbone:", backbone_allele, file=sys.stderr)
+                print("msf_allele_seq  :", msf_allele_seq, file=sys.stderr)
+                print("msf_backbone_seq:", msf_backbone_seq, file=sys.stderr)
+                print(file=sys.stderr)
 
         allele_dic = {}
         for allele_id, allele_seq in allele_seqs:
@@ -542,7 +542,7 @@
         # Sanity check
         assert len(allele_dic) == len(allele_repeat_msf)
         repeat_len = -1
-        for repeat_msf in allele_repeat_msf.values():
+        for repeat_msf in list(allele_repeat_msf.values()):
             if repeat_len < 0:
                 repeat_len = len(repeat_msf)
             else:
@@ -551,11 +551,11 @@
         # Creat full multiple sequence alignment
         ref_allele_id = CODIS_ref_name[locus_name]
         allele_msf = {}
-        for allele_id, repeat_msf in allele_repeat_msf.items():
+        for allele_id, repeat_msf in list(allele_repeat_msf.items()):
             allele_msf[allele_id] = ref_allele_left + repeat_msf + ref_allele_right
 
         # Make sure the length of allele ID is short, less than 20 characters
-        max_allele_id_len = max([len(allele_id) for allele_id in allele_dic.keys()])
+        max_allele_id_len = max([len(allele_id) for allele_id in list(allele_dic.keys())])
         assert max_allele_id_len < 20
 
         # Write MSF (multiple sequence alignment file)
@@ -563,17 +563,17 @@
         msf_fname = "%s_gen.msf" % locus_name
         msf_file = open(msf_fname, 'w')
         for s in range(0, msf_len, 50):
-            for allele_id, msf in allele_msf.items():
+            for allele_id, msf in list(allele_msf.items()):
                 assert len(msf) == msf_len
                 allele_name = "%s*%s" % (locus_name, allele_id)
-                print >> msf_file, "%20s" % allele_name,
+                print("%20s" % allele_name, end=' ', file=msf_file)
                 for s2 in range(s, min(msf_len, s + 50), 10):
-                    print >> msf_file, " %s" % msf[s2:s2+10],
-                print >> msf_file
+                    print(" %s" % msf[s2:s2+10], end=' ', file=msf_file)
+                print(file=msf_file)
 
             if s + 50 >= msf_len:
                 break
-            print >> msf_file
+            print(file=msf_file)
         msf_file.close()
 
         # Write FASTA file
@@ -581,9 +581,9 @@
         fasta_file = open(fasta_fname, 'w')
         for allele_id, allele_seq in allele_seqs:
             gen_seq = ref_allele_left + allele_seq + ref_allele_right
-            print >> fasta_file, ">%s*%s %d bp" % (locus_name, allele_id, len(gen_seq))
+            print(">%s*%s %d bp" % (locus_name, allele_id, len(gen_seq)), file=fasta_file)
             for s in range(0, len(gen_seq), 60):
-                print >> fasta_file, gen_seq[s:s+60]
+                print(gen_seq[s:s+60], file=fasta_file)
         fasta_file.close()
 
 
--- hisat2.orig/hisatgenotype_modules/hisatgenotype_extract_codis_data.py
+++ hisat2/hisatgenotype_modules/hisatgenotype_extract_codis_data.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2017, Daehwan Kim <infphilo@gmail.com>
@@ -73,7 +73,7 @@
             continue
         url = "%s/str_%s.htm" % (base_url, locus_name)
         content = get_html(url).split("\r\n")
-        content = map(lambda x: x.strip(), content)
+        content = [x.strip() for x in content]
         content2 = []
         for line in content:
             if line.startswith("<t") or \
@@ -121,7 +121,7 @@
                 l += 1
 
         for allele_id, repeat_st in alleles:
-            print >> codis_data_file, "%s\t%s\t%s" % (locus_name, allele_id, repeat_st)
+            print("%s\t%s\t%s" % (locus_name, allele_id, repeat_st), file=codis_data_file)
 
     codis_data_file.close()
 
--- hisat2.orig/hisatgenotype_modules/hisatgenotype_extract_cyp_data.py
+++ hisat2/hisatgenotype_modules/hisatgenotype_extract_cyp_data.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2016, Raymon Cao <rcao5@jhu.edu> and Daehwan Kim <infphilo@gmail.com>
@@ -88,8 +88,8 @@
         # Open file to write on
         cyp_file = open("cyp_var_files/%s.var" % (cyp_gene_name), 'w')
         
-        print >> sys.stderr, cyp_url, cyp_gene_name
-        print >> cyp_file, cyp_url, cyp_gene_name
+        print(cyp_url, cyp_gene_name, file=sys.stderr)
+        print(cyp_url, cyp_gene_name, file=cyp_file)
 
         cyp_output = get_html(cyp_url)
         if cyp_output == "":
@@ -155,11 +155,11 @@
                 try:
                     assert len(varInfo) == 1
                 except:
-                    varInfo = filter(lambda a: a != 'None', varInfo)
+                    varInfo = [a for a in varInfo if a != 'None']
                 
         
-            if isinstance(alleleName, basestring):
-                print >> cyp_file, (str(alleleName) + "\t" + ','.join(varInfo))
+            if isinstance(alleleName, str):
+                print((str(alleleName) + "\t" + ','.join(varInfo)), file=cyp_file)
             
         cyp_file.close()
 
@@ -169,7 +169,7 @@
 """
 
 def checkNTloc(fasta_fileName,var_fileName,gene_name):
-    print "\nGene: %s" % gene_name
+    print("\nGene: %s" % gene_name)
     seq = ""
     for line in open(fasta_fileName,'r'):
         if line[0] == '>':
@@ -180,11 +180,11 @@
     cyp_var_dict = makeVarDict(cyp_var_file)
     cyp_var_file.close()
 
-    print "len:", len(seq)
+    print("len:", len(seq))
     varsPos = set()
     varsNeg = set()
 
-    for varList in cyp_var_dict.values():
+    for varList in list(cyp_var_dict.values()):
         for var in varList:
             if ">" in var: # is SNP
                 posNt = int(var[:-3])
@@ -219,7 +219,7 @@
                     try:
                         assert posNt[1] - posNt[0] + 1 == len(ntDel)
                     except AssertionError:
-                        print "Incorrect deletion format: %s , skipping variation" % (var)
+                        print("Incorrect deletion format: %s , skipping variation" % (var))
                         '''sys.exit(1)'''
                         continue
                     ntDelList = list(ntDel)
@@ -251,12 +251,12 @@
                 align_score += 1
 
         scorePos[i] = align_score
-    oSetPos = max(scorePos.iteritems(), key=operator.itemgetter(1))[0]
-    print "Positive postitions offset: %d" % oSetPos
-    print "Score: %d out of %d\n" % (scorePos[oSetPos], len(varsPos))
+    oSetPos = max(iter(scorePos.items()), key=operator.itemgetter(1))[0]
+    print("Positive postitions offset: %d" % oSetPos)
+    print("Score: %d out of %d\n" % (scorePos[oSetPos], len(varsPos)))
     
 
-    print "Checking negative position offset: %d" % (oSetPos + 1)
+    print("Checking negative position offset: %d" % (oSetPos + 1))
     align_score = 0
     oSetNeg = oSetPos + 1
     for var in varsNeg:
@@ -270,7 +270,7 @@
         
         if seq[pos + oSetNeg] == base:
             align_score += 1
-    print "Score: %d out of %d\n\n" % (align_score, len(varsNeg))
+    print("Score: %d out of %d\n\n" % (align_score, len(varsNeg)))
 
     if len(varsNeg) == 0 and len(varsPos) != 0:
         return oSetPos, oSetNeg, float(scorePos[oSetPos])/float(len(varsPos)), 1.0, float(scorePos[oSetPos] + align_score)/float(len(varsPos) + len(varsNeg))
@@ -344,7 +344,7 @@
             assert not alleleName in alleleVarDict
             alleleVarDict[alleleName] = set(varList)
         except:
-            print >> sys.stdout, ("Warning, %s allele is already represented" % alleleName)
+            print(("Warning, %s allele is already represented" % alleleName), file=sys.stdout)
             alleleVarDict[alleleName] = alleleVarDict[alleleName] | set(varList)
 
     return alleleVarDict
@@ -386,7 +386,7 @@
         if len(blast_allele_var) > 0:
             cyp_var_dict[gene_name.upper() + '*REFGRCH38P7'] = set(blast_allele_var)
     except IOError:
-        print('\t%s blast file was skipped.' % gene_name)
+        print(('\t%s blast file was skipped.' % gene_name))
 
     cyp_faFile = open("cyp_fasta/%s.fasta" % gene_name,'r')
     cyp_seq = extractSeq(cyp_faFile)
@@ -398,7 +398,7 @@
 
     # Building backbone structure (augment length with insertions)
     longestIns = {} # { key = position : value = length }
-    for allele,varList in cyp_var_dict.items():
+    for allele,varList in list(cyp_var_dict.items()):
         for var in varList:
             if not "ins" in var:
                 continue
@@ -411,7 +411,7 @@
             try:
                 assert correctFormat
             except:
-                print >> sys.stdout, "\tIncorrect format for insertion: variation %s on allele %s" % (var, allele)
+                print("\tIncorrect format for insertion: variation %s on allele %s" % (var, allele), file=sys.stdout)
                 continue
 
             # convert to position in string
@@ -450,7 +450,7 @@
     map_cyp = create_map(preBackbone_seq) # { Index of bp in original seq : Actual index in string }
     
 
-    for allele,varList in cyp_var_dict.items():
+    for allele,varList in list(cyp_var_dict.items()):
         for var in varList:
             isSnp = False
             isDel = False
@@ -481,15 +481,15 @@
                         pos = pos + oSetNeg
 
                 if pos < 0 or pos > len(cyp_seq) - 1:
-                    print >> sys.stdout, "\tWarning: position %d out of bounds" % (dbPos)
-                    print >> sys.stdout, "\t\tError occured on variation %s on allele %s. Skipping variation." % (var, allele)
+                    print("\tWarning: position %d out of bounds" % (dbPos), file=sys.stdout)
+                    print("\t\tError occured on variation %s on allele %s. Skipping variation." % (var, allele), file=sys.stdout)
                     continue
                     
                 try:
                     assert(preBackbone_seq[map_cyp[pos]] == ntChange[0]) # nt at pos in seq must match database
                 except:
-                    print >> sys.stdout, "\tWarning: position %d in sequence contains %s, but expected %s from database" % (dbPos, preBackbone_seq[map_cyp[pos]], ntChange[0])
-                    print >> sys.stdout, "\t\tError occured on variation %s on allele %s. Skipping variation." % (var, allele)
+                    print("\tWarning: position %d in sequence contains %s, but expected %s from database" % (dbPos, preBackbone_seq[map_cyp[pos]], ntChange[0]), file=sys.stdout)
+                    print("\t\tError occured on variation %s on allele %s. Skipping variation." % (var, allele), file=sys.stdout)
                     continue
                 
                 # Adding to msf table
@@ -519,8 +519,8 @@
                 skipDel = False
                 for i in range(len(pos)):
                     if pos[i] < 0 or pos[i] > len(cyp_seq) - 1:
-                        print >> sys.stdout, "\tWarning: position %d out of bounds" % (dbPos[i])
-                        print >> sys.stdout, "\t\tError occured on variation %s on allele %s. Skipping variation." % (var, allele)
+                        print("\tWarning: position %d out of bounds" % (dbPos[i]), file=sys.stdout)
+                        print("\t\tError occured on variation %s on allele %s. Skipping variation." % (var, allele), file=sys.stdout)
                         skipDel = True
 
                 if skipDel:
@@ -530,15 +530,15 @@
                 try:
                     assert pos[1] - pos[0] + 1 == len(ntDel)
                 except:
-                    print >> sys.stdout, "\tIncorrect deletion data with %s on allele %s. Skipping variation." % (var, allele)
+                    print("\tIncorrect deletion data with %s on allele %s. Skipping variation." % (var, allele), file=sys.stdout)
                     continue
                             
                 try:
                     assert preBackbone_seq[ map_cyp[pos[0]] : map_cyp[pos[1]] + 1 ] == ntDel
                 except:
-                    print >> sys.stdout, "\tWarning, positions %d to %d in sequence contains %s, but expected %s from database" % \
-                          (dbPos[0], dbPos[1], preBackbone_seq[ map_cyp[pos[0]] : map_cyp[pos[1]] + 1 ], ntDel)
-                    print >> sys.stdout, "\t\tError occured on variation %s on allele %s. Skipping variation." % (var, allele)
+                    print("\tWarning, positions %d to %d in sequence contains %s, but expected %s from database" % \
+                          (dbPos[0], dbPos[1], preBackbone_seq[ map_cyp[pos[0]] : map_cyp[pos[1]] + 1 ], ntDel), file=sys.stdout)
+                    print("\t\tError occured on variation %s on allele %s. Skipping variation." % (var, allele), file=sys.stdout)
                     continue
 
 
@@ -559,7 +559,7 @@
                 try:
                     assert pos[1] - pos[0] == 1
                 except AssertionError:
-                    print >> sys.stdout, "\tIncorrect insertion data with %s on allele %s. Skipping variation." % (var, allele)
+                    print("\tIncorrect insertion data with %s on allele %s. Skipping variation." % (var, allele), file=sys.stdout)
                     continue 
                 ntIns = var.split('ins')[1]
                 for nt in ntIns:
@@ -575,8 +575,8 @@
                 skipIns = False
                 for i in range(len(pos)):
                     if pos[i] < 0 or pos[i] > len(cyp_seq) - 1:
-                        print >> sys.stdout, "Warning: position %d out of bounds" % (dbPos[i])
-                        print >> sys.stdout, "\tError occured on variation %s on allele %s. Skipping variation." % (var, allele)
+                        print("Warning: position %d out of bounds" % (dbPos[i]), file=sys.stdout)
+                        print("\tError occured on variation %s on allele %s. Skipping variation." % (var, allele), file=sys.stdout)
                         skipIns = True
 
                 if skipIns:
@@ -597,7 +597,7 @@
 
     # Sanity checking
     seq_len = 0
-    for allele, msf_seq in msfTable.items():
+    for allele, msf_seq in list(msfTable.items()):
         if seq_len == 0:
             seq_len = len(msf_seq)
         else:
@@ -607,7 +607,7 @@
     # Follow MSF style of IMGT/HLA database
     msfFile = open('cyp_msf/%s_gen.msf' % gene_name[3:].upper(),'w')
     for i in range(0, seq_len, 50):
-        for allele, msf_seq in msfTable.items():
+        for allele, msf_seq in list(msfTable.items()):
             output = "%12s" % allele[3:].upper()
             for j in range(i, i+50, 10):
                 if j >= seq_len:
@@ -617,8 +617,8 @@
                 else:
                     output += " "
                 output += msf_seq[j:j+10]
-            print >> msfFile, output
-        print >> msfFile
+            print(output, file=msfFile)
+        print(file=msfFile)
 
     msfFile.close()
 
@@ -636,7 +636,7 @@
     for gene_name in gene_names:
         oSetPos, oSetNeg, oSetScorePos, oSetScoreNeg, tot_score = checkNTloc("cyp_fasta/%s.fasta" % gene_name,"cyp_var_files/%s.var" % gene_name,gene_name)
         if not (tot_score >= 0.95):
-            print "\tLess than 95% match, skipping gene."
+            print("\tLess than 95% match, skipping gene.")
             continue
         
         makeMSF(gene_name, oSetPos, oSetNeg)
@@ -750,7 +750,7 @@
         msf_dict = readMSF(msf_file) # { Allele name : MSF sequence }
         msf_file.close()
     except IOError:
-        print("\t%s msf file was skipped.\n" % (gene_name))
+        print(("\t%s msf file was skipped.\n" % (gene_name)))
         return
 
     var_file = open(var_fname,'r')
@@ -762,7 +762,7 @@
         if len(blast_allele_var) > 0:
             var_dict[gene_name.upper() + '*REFGRCH38P7'] = set(blast_allele_var)
     except IOError:
-        print('\t%s blast file was skipped.' % gene_name)
+        print(('\t%s blast file was skipped.' % gene_name))
     
     fa_file = open(fasta_filename,'r')
     oriSeq = extractSeq(fa_file)
@@ -771,7 +771,7 @@
 
     # Find reference allele
     ref_allele = ''
-    for allele_name in var_dict.keys():
+    for allele_name in list(var_dict.keys()):
         if len(var_dict[allele_name]) == 1 and list(var_dict[allele_name])[0] == "None":
             assert ref_allele == ''
             ref_allele = allele_name
@@ -783,25 +783,25 @@
 
     try:
         assert msf_dict[ref_allele].replace('.','') == oriSeq
-        print("Sequences match for reference allele %s" % ref_allele)
+        print(("Sequences match for reference allele %s" % ref_allele))
     except AssertionError:
-        print("Warning: sequences do not match for reference allele %s" % ref_allele)
+        print(("Warning: sequences do not match for reference allele %s" % ref_allele))
         sys.exit(1)
 
 
     # Check all alleles are included
     try:
-        assert set([k.upper() for k in msf_dict.keys()]).issubset(set([k.upper() for k in var_dict.keys()]))
+        assert set([k.upper() for k in list(msf_dict.keys())]).issubset(set([k.upper() for k in list(var_dict.keys())]))
     except AssertionError:
         print("Extra alleles in MSF!\n")
-        print(sorted(msf_dict.keys()))
+        print((sorted(msf_dict.keys())))
         print("\n\n")
-        print(sorted(var_dict.keys()))
+        print((sorted(var_dict.keys())))
         sys.exit(1)
 
 
     # Convert from database positions to sequence positions (using offset)
-    for allele, var_list in var_dict.items():
+    for allele, var_list in list(var_dict.items()):
         oSet_var_list = []
         for var in var_list:
             if '>' in var: # snp
@@ -818,7 +818,7 @@
                 if pos < 0 or pos > len(oriSeq) - 1: # out of bounds
                     continue
                 if oriSeq[pos] != ntSnp[0]: # mismatch
-                    print('\tMismatch on variation %s' % var)
+                    print(('\tMismatch on variation %s' % var))
                     continue
 
                 oSet_var = str(pos) + ntSnp[0] + '>' + ntSnp[1]
@@ -844,7 +844,7 @@
                         if pos[i] < 0 or pos[i] > len(oriSeq) - 1: # out of bounds
                             skipDel = True
                 if (oriSeq[ pos[0] : pos[1] + 1 ] != ntDel): # mismatch
-                    print('\tMismatch on variation %s' % var)
+                    print(('\tMismatch on variation %s' % var))
                     continue
 
                 if skipDel:
@@ -869,7 +869,7 @@
                 try:
                     assert pos[1] - pos[0] == 1
                 except AssertionError:
-                    print('\tIncorrect insertion format on variation %s' % var)
+                    print(('\tIncorrect insertion format on variation %s' % var))
                     continue
                 ntIns = var.split('ins')[1]
                 for nt in ntIns:
@@ -901,7 +901,7 @@
 
     # Check variants created from MSF file against variants list
     num_correct_alleles = 0
-    for allele, msf_seq in msf_dict.items():
+    for allele, msf_seq in list(msf_dict.items()):
         if allele == ref_allele:
             num_correct_alleles += 1
             continue
@@ -914,12 +914,12 @@
         except AssertionError:
             incorrect_msf_entries.append(allele)
             print('\n')
-            print('\t\tVar File:\t' + str(var_dict[allele]))
-            print('\t\tMSF File:\t' + str(set(msf_var_list)))
-            print('\t\tDifference:\t' + str(var_dict[allele] - set(msf_var_list)) + '\n')
+            print(('\t\tVar File:\t' + str(var_dict[allele])))
+            print(('\t\tMSF File:\t' + str(set(msf_var_list))))
+            print(('\t\tDifference:\t' + str(var_dict[allele] - set(msf_var_list)) + '\n'))
             '''sys.exit(1)'''
 
-    print("\t%d out of %d alleles have correct msf sequences\n" % (num_correct_alleles, len(msf_dict)))
+    print(("\t%d out of %d alleles have correct msf sequences\n" % (num_correct_alleles, len(msf_dict))))
 
 def check_msf_files():
     print("\nChecking MSF files:")
@@ -927,7 +927,7 @@
     for gene_name in gene_names:
         checkMSFfile(gene_name, 'cyp_msf/%s_gen.msf' % gene_name[3:].upper(), 'cyp_var_files/%s.var' % gene_name, 'cyp_fasta/%s.fasta' % gene_name)
 
-    print('\n\n%d incorrect msf entries on alleles %s\n' % (len(incorrect_msf_entries), str(incorrect_msf_entries)))
+    print(('\n\n%d incorrect msf entries on alleles %s\n' % (len(incorrect_msf_entries), str(incorrect_msf_entries))))
 
 
 """
@@ -940,19 +940,19 @@
         msf_seq_dict = readMSF(msf_file)
         msf_file.close()
     except IOError:
-        print("\t%s msf file was skipped." % (gene_name))
+        print(("\t%s msf file was skipped." % (gene_name)))
         return
 
     gen_fasta_file = open('gen_fasta/%s_gen.fasta' % gene_name[3:].upper(), 'w')
     
-    for allele, seq in msf_seq_dict.items():
+    for allele, seq in list(msf_seq_dict.items()):
         seq = seq.replace('.','')
-        print >> gen_fasta_file, ('>' + allele[3:].upper() + ' ' + str(len(seq)) + ' bp')
+        print(('>' + allele[3:].upper() + ' ' + str(len(seq)) + ' bp'), file=gen_fasta_file)
         seq_lines = [seq[i:i+line_length] for i in range(0, len(seq), line_length)]
-        print >> gen_fasta_file, ('\n'.join(seq_lines))
+        print(('\n'.join(seq_lines)), file=gen_fasta_file)
 
     gen_fasta_file.close()
-    print('%s_gen.fasta completed' % gene_name)
+    print(('%s_gen.fasta completed' % gene_name))
 
 def build_gen_fasta_files():
     os.system('mkdir gen_fasta')
--- hisat2.orig/hisatgenotype_modules/hisatgenotype_typing_common.py
+++ hisat2/hisatgenotype_modules/hisatgenotype_typing_common.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Copyright 2017, Daehwan Kim <infphilo@gmail.com>
 #
@@ -253,12 +253,12 @@
     # DK - debugging purposes
     # extract_cmd += ["--ext-seq", "300"]
     if verbose:
-        print >> sys.stderr, "\tRunning:", ' '.join(extract_cmd)
+        print("\tRunning:", ' '.join(extract_cmd), file=sys.stderr)
     proc = subprocess.Popen(extract_cmd, stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w'))
     proc.communicate()
 
     if not check_files(fnames):
-        print >> sys.stderr, "Error: hisatgenotype_extract_vars failed!"
+        print("Error: hisatgenotype_extract_vars failed!", file=sys.stderr)
         sys.exit(1)
 
         
@@ -281,11 +281,11 @@
                              "%s_backbone.fa" % base,
                              "%s.graph" % base]
                 if verbose:
-                    print >> sys.stderr, "\tRunning:", ' '.join(build_cmd)
+                    print("\tRunning:", ' '.join(build_cmd), file=sys.stderr)
                 proc = subprocess.Popen(build_cmd, stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w'))
                 proc.communicate()        
                 if not check_files(hisat2_graph_index_fnames):
-                    print >> sys.stderr, "Error: indexing HLA failed!  Perhaps, you may have forgotten to build hisat2 executables?"
+                    print("Error: indexing HLA failed!  Perhaps, you may have forgotten to build hisat2 executables?", file=sys.stderr)
                     sys.exit(1)
         # Build HISAT2 linear indexes based on the above information
         else:
@@ -298,7 +298,7 @@
                 proc = subprocess.Popen(build_cmd, stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w'))
                 proc.communicate()        
                 if not check_files(hisat2_linear_index_fnames):
-                    print >> sys.stderr, "Error: indexing HLA failed!"
+                    print("Error: indexing HLA failed!", file=sys.stderr)
                     sys.exit(1)                    
     else:
         # Build Bowtie2 indexes based on the above information
@@ -312,7 +312,7 @@
             proc = subprocess.Popen(build_cmd, stdout=open("/dev/null", 'w'))
             proc.communicate()        
             if not check_files(bowtie2_index_fnames):
-                print >> sys.stderr, "Error: indexing HLA failed!"
+                print("Error: indexing HLA failed!", file=sys.stderr)
                 sys.exit(1)
 
                     
@@ -497,7 +497,7 @@
 
             # Extract variants included in each allele
             var_ids = []
-            for var_id, allele_list in Links.items():
+            for var_id, allele_list in list(Links.items()):
                 if allele_name in allele_list:
                     var_ids.append(var_id)
 
@@ -574,8 +574,8 @@
             query_name = "%d|%s_%s" % (read_i + 1, "LR"[idx-1], reads[read_i][1])
             if len(query_name) > 254:
                 query_name = query_name[:254]
-            print >> read_file, ">%s" % query_name
-            print >> read_file, reads[read_i][0]
+            print(">%s" % query_name, file=read_file)
+            print(reads[read_i][0], file=read_file)
         read_file.close()
     write_reads(reads_1, 1)
     write_reads(reads_2, 2)
@@ -628,7 +628,7 @@
         aligner_cmd += ["-1", "%s" % read_fname[0],
                         "-2", "%s" % read_fname[1]]
     if verbose >= 1:
-        print >> sys.stderr, ' '.join(aligner_cmd)
+        print(' '.join(aligner_cmd), file=sys.stderr)
     align_proc = subprocess.Popen(aligner_cmd,
                                   stdout=subprocess.PIPE,
                                   stderr=open("/dev/null", 'w'))
@@ -732,7 +732,7 @@
         num_nt = sum(nt_dic.values())
         nt_set = []
         if num_nt >= 20:
-            for nt, count in nt_dic.items():
+            for nt, count in list(nt_dic.items()):
                 if nt not in "ACGT":
                     continue
                 if count >= num_nt * 0.2 or count >= 7:
@@ -741,7 +741,7 @@
 
     # Sort variants
     var_list = [[] for i in range(len(mpileup))]
-    for var_id, value in vars.items():
+    for var_id, value in list(vars.items()):
         var_type, var_pos, var_data = value
         assert var_pos < len(var_list)
         var_list[var_pos].append([var_id, var_type, var_data])
@@ -752,7 +752,7 @@
         nt_dic = mpileup[i][1]
         ref_nt = ref_seq[i]
         new_nt_dic = {}
-        for nt, count in nt_dic.items():
+        for nt, count in list(nt_dic.items()):
             var_id = ""
             if nt == 'D':
                 if i <= skip_i:
@@ -828,7 +828,7 @@
         else:
             concordant = False
 
-        NH, YT = sys.maxint, ""
+        NH, YT = sys.maxsize, ""
         for i in range(11, len(cols)):
              col = cols[i]
              if col.startswith("NH"):
@@ -880,7 +880,7 @@
 """
 def prob_diff(prob1, prob2):
     diff = 0.0
-    for allele in prob1.keys():
+    for allele in list(prob1.keys()):
         if allele in prob2:
             diff += abs(prob1[allele] - prob2[allele])
         else:
@@ -908,20 +908,20 @@
 def single_abundance(Gene_cmpt, Gene_length, exonic = False):
     def normalize(prob):
         total = sum(prob.values())
-        for allele, mass in prob.items():
+        for allele, mass in list(prob.items()):
             prob[allele] = mass / total        
 
     def normalize_len(prob, length):
         total = 0
-        for allele, mass in prob.items():
+        for allele, mass in list(prob.items()):
             assert allele in length
             total += (mass / length[allele])
-        for allele, mass in prob.items():
+        for allele, mass in list(prob.items()):
             assert allele in length
             prob[allele] = mass / length[allele] / total
 
     Gene_prob, Gene_prob_next = {}, {}
-    for cmpt, count in Gene_cmpt.items():
+    for cmpt, count in list(Gene_cmpt.items()):
         alleles = cmpt.split('-')
         for allele in alleles:
             if allele not in Gene_prob:
@@ -934,7 +934,7 @@
 
     def next_prob(Gene_cmpt, Gene_prob, Gene_length):
         Gene_prob_next = {}
-        for cmpt, count in Gene_cmpt.items():
+        for cmpt, count in list(Gene_cmpt.items()):
             alleles = cmpt.split('-')
             alleles_prob = 0.0
             for allele in alleles:
@@ -960,7 +960,7 @@
             return Gene_prob
         Gene_prob2 = {}
         max_prob = max(Gene_prob.values())
-        for allele, prob in Gene_prob.items():
+        for allele, prob in list(Gene_prob.items()):
             if prob >= max_prob / 10.0:
                 Gene_prob2[allele] = prob
         return Gene_prob2
@@ -976,14 +976,14 @@
             Gene_prob_next2 = next_prob(Gene_cmpt, Gene_prob_next, Gene_length)
             sum_squared_r, sum_squared_v = 0.0, 0.0
             p_r, p_v = {}, {}
-            for a in Gene_prob.keys():
+            for a in list(Gene_prob.keys()):
                 p_r[a] = Gene_prob_next[a] - Gene_prob[a]
                 sum_squared_r += (p_r[a] * p_r[a])
                 p_v[a] = Gene_prob_next2[a] - Gene_prob_next[a] - p_r[a]
                 sum_squared_v += (p_v[a] * p_v[a])
             if sum_squared_v > 0.0:
                 gamma = -math.sqrt(sum_squared_r / sum_squared_v)
-                for a in Gene_prob.keys():
+                for a in list(Gene_prob.keys()):
                     Gene_prob_next2[a] = max(0.0, Gene_prob[a] - 2 * gamma * p_r[a] + gamma * gamma * p_v[a]);
                 Gene_prob_next = next_prob(Gene_cmpt, Gene_prob_next2, Gene_length)
 
@@ -996,10 +996,10 @@
 
         # DK - debugging purposes
         if iter % 10 == 0 and False:
-            print >> sys.stderr, "iter", iter
-            for allele, prob in Gene_prob.items():
+            print("iter", iter, file=sys.stderr)
+            for allele, prob in list(Gene_prob.items()):
                 if prob >= 0.01:
-                    print >> sys.stderr, "\t", iter, allele, prob
+                    print("\t", iter, allele, prob, file=sys.stderr)
         
         iter += 1
         
@@ -1008,7 +1008,7 @@
         normalize(Gene_prob)
     else:
         normalize_len(Gene_prob, Gene_length)
-    Gene_prob = [[allele, prob] for allele, prob in Gene_prob.items()]
+    Gene_prob = [[allele, prob] for allele, prob in list(Gene_prob.items())]
     Gene_prob = sorted(Gene_prob, cmp=Gene_prob_cmp)
     return Gene_prob
 
@@ -1033,7 +1033,7 @@
                      verbose):
     haplotype_alts_left, haplotype_alts_right = {}, {}
     second_order_haplotypes = set()
-    for allele_name, vars in allele_vars.items():
+    for allele_name, vars in list(allele_vars.items()):
         for v in range(len(vars) - 1):
             ht = vars[v] + "-" + vars[v+1]
             second_order_haplotypes.add(ht)
@@ -1065,7 +1065,7 @@
                 prev_id = haplotype[1]        
 
             var_i = lower_bound(rev_Var_list, pos + 1)
-            for var_j in reversed(range(0, var_i)):
+            for var_j in reversed(list(range(0, var_i))):
                 _, var_id = rev_Var_list[var_j]
                 var_type, var_pos, var_data = Vars[var_id]
                 if var_type == "deletion":
@@ -1229,16 +1229,16 @@
 
     # Print alternative haplotypes / Sanity check
     def print_haplotype_alts(haplotype_alts):
-        for haplotype, haplotype_set in haplotype_alts.items():
-            if verbose: print "\t%s:" % haplotype, haplotype_set
+        for haplotype, haplotype_set in list(haplotype_alts.items()):
+            if verbose: print("\t%s:" % haplotype, haplotype_set)
             haplotype_seq = get_haplotype_seq(haplotype.split('-'))
             for haplotype_alt in haplotype_set:
                 haplotype_alt_seq = get_haplotype_seq(haplotype_alt.split('-'))
                 assert haplotype_seq == haplotype_alt_seq            
 
-    if verbose: print "number of left haplotypes:", len(haplotype_alts_left)
+    if verbose: print("number of left haplotypes:", len(haplotype_alts_left))
     print_haplotype_alts(haplotype_alts_left)
-    if verbose: print "number of right haplotypes:", len(haplotype_alts_right)
+    if verbose: print("number of right haplotypes:", len(haplotype_alts_right))
     print_haplotype_alts(haplotype_alts_right)
 
     return haplotype_alts_left, haplotype_alts_right
@@ -1286,7 +1286,7 @@
 
     # Left direction
     found = False
-    for i in reversed(range(len(cmp_list))):
+    for i in reversed(list(range(len(cmp_list)))):
         i_found = False
         cmp_i = cmp_list[i]
         type, cur_left, length = cmp_i[:3]
@@ -1308,7 +1308,7 @@
         else:
             cur_ht_str = "%d-%s" % (left, '-'.join(cur_ht))
         ht_i = lower_bound(Alts_left_list, cur_right + 1)
-        for ht_j in reversed(range(0, min(ht_i + 1, len(Alts_left_list)))):
+        for ht_j in reversed(list(range(0, min(ht_i + 1, len(Alts_left_list))))):
             ht_pos, ht = Alts_left_list[ht_j]
             if ht_pos < cur_left:
                 break            
@@ -1333,15 +1333,15 @@
             i_found = True
 
             if debug:
-                print cmp_list[:i+1]
-                print "\t", cur_ht, "vs", Alts_left_list[ht_j], ht_pos
+                print(cmp_list[:i+1])
+                print("\t", cur_ht, "vs", Alts_left_list[ht_j], ht_pos)
 
             _, rep_ht = Alts_left_list[ht_j]
 
             if debug:
-                print "DK1:", cmp_i, cmp_list
-                print "DK2:", rep_ht, Alts_left[rep_ht]
-                print "DK3:", left, right, ht_pos
+                print("DK1:", cmp_i, cmp_list)
+                print("DK2:", rep_ht, Alts_left[rep_ht])
+                print("DK3:", left, right, ht_pos)
 
             for alt_ht_str in Alts_left[rep_ht]:
                 alt_ht = alt_ht_str.split('-')
@@ -1391,7 +1391,7 @@
                     left_alt_set.add(part_alt_ht_str)
                         
                 if debug:
-                    print "\t\t", cur_left, alt_ht_str
+                    print("\t\t", cur_left, alt_ht_str)
 
         if i_found:
             if not found:
@@ -1452,9 +1452,9 @@
             _, rep_ht = Alts_right_list[ht_j]
 
             if debug:
-                print "DK1:", cmp_i, cmp_list
-                print "DK2:", rep_ht, Alts_right[rep_ht]
-                print "DK3:", left, right, ht_pos
+                print("DK1:", cmp_i, cmp_list)
+                print("DK2:", rep_ht, Alts_right[rep_ht])
+                print("DK3:", left, right, ht_pos)
 
             for alt_ht_str in Alts_right[rep_ht]:
                 alt_ht = alt_ht_str.split('-')
@@ -1522,12 +1522,12 @@
         if ht == "":
             continue
         if ht in ht_set_:
-            print >> sys.stderr, "Error) %s should not be in" % ht, ht_set_
+            print("Error) %s should not be in" % ht, ht_set_, file=sys.stderr)
 
             # DK - debugging purposes
-            print "DK: cmp_list_range: [%d, %d]" % (cmp_left, cmp_right)
-            print "DK: cmp_list:", cmp_list
-            print "DK: left_alt_set:", left_alt_set, "right_alt_set:", right_alt_set
+            print("DK: cmp_list_range: [%d, %d]" % (cmp_left, cmp_right))
+            print("DK: cmp_list:", cmp_list)
+            print("DK: left_alt_set:", left_alt_set, "right_alt_set:", right_alt_set)
             
             assert False
         ht_set_.add(ht)
@@ -1536,14 +1536,14 @@
         if ht == "":
             continue
         if ht in ht_set_:
-            print >> sys.stderr, "Error) %s should not be in" % ht, ht_set_
+            print("Error) %s should not be in" % ht, ht_set_, file=sys.stderr)
             assert False
         ht_set_.add(ht)
 
     if debug:
-        print "cmp_list_range: [%d, %d]" % (cmp_left, cmp_right)
-        print "left  alt set:", left_alt_set
-        print "right alt set:", right_alt_set
+        print("cmp_list_range: [%d, %d]" % (cmp_left, cmp_right))
+        print("left  alt set:", left_alt_set)
+        print("right alt set:", right_alt_set)
     
     return cmp_left, cmp_right, list(left_alt_set), list(right_alt_set)
 
--- hisat2.orig/hisatgenotype_scripts/compare_HLA_Omixon.py
+++ hisat2/hisatgenotype_scripts/compare_HLA_Omixon.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 import sys, os
 from argparse import ArgumentParser, FileType
@@ -52,8 +52,8 @@
 
     for gene in hla_list:
         count, count_10 = [0, 0, 0], [0, 0, 0]
-        print >> sys.stderr, gene
-        for sample in omixon_hla.keys():
+        print(gene, file=sys.stderr)
+        for sample in list(omixon_hla.keys()):
             if sample not in hisat_hla:
                 continue
             hisat_sample = hisat_hla[sample]
@@ -106,8 +106,8 @@
         if sum(count) <= 0:
             continue
         
-        print >> sys.stderr, "\tTop two\t0: %d, 1: %d, 2: %d (%.2f%%)" % (count[0], count[1], count[2], (count[1] + count[2] * 2) / float(sum(count) * 2) * 100.0)
-        print >> sys.stderr, "\tTop ten\t0: %d, 1: %d, 2: %d (%.2f%%)" % (count_10[0], count_10[1], count_10[2], (count_10[1] + count_10[2] * 2) / float(sum(count_10) * 2) * 100.0)
+        print("\tTop two\t0: %d, 1: %d, 2: %d (%.2f%%)" % (count[0], count[1], count[2], (count[1] + count[2] * 2) / float(sum(count) * 2) * 100.0), file=sys.stderr)
+        print("\tTop ten\t0: %d, 1: %d, 2: %d (%.2f%%)" % (count_10[0], count_10[1], count_10[2], (count_10[1] + count_10[2] * 2) / float(sum(count_10) * 2) * 100.0), file=sys.stderr)
         
 
 if __name__ == "__main__":
--- hisat2.orig/hisatgenotype_scripts/extract_Omixon_HLA.py
+++ hisat2/hisatgenotype_scripts/extract_Omixon_HLA.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2016, Daehwan Kim <infphilo@gmail.com>
@@ -44,9 +44,9 @@
                     nuc_alleles[gene] = set()
                 nuc_alleles[gene].add(allele)
 
-    print >> sys.stderr, "IMGTHLA"
-    for gene, alleles in nuc_alleles.items():
-        print >> sys.stderr, "\t%s: %d alleles" % (gene, len(alleles))
+    print("IMGTHLA", file=sys.stderr)
+    for gene, alleles in list(nuc_alleles.items()):
+        print("\t%s: %d alleles" % (gene, len(alleles)), file=sys.stderr)
 
     # Read HLA alleles from Omixon data
     omixon_alleles = {}
@@ -95,11 +95,11 @@
             omixon_alleles[gene].add(allele2)
             prev_allele1, prev_allele2 = allele1, allele2
 
-            print "%s\t%s\t%s" % (genome, allele1, allele2)
+            print("%s\t%s\t%s" % (genome, allele1, allele2))
 
-    print >> sys.stderr, "Omixon"
-    for gene, alleles in omixon_alleles.items():
-        print >> sys.stderr, "\t%s: %d alleles" % (gene, len(alleles))
+    print("Omixon", file=sys.stderr)
+    for gene, alleles in list(omixon_alleles.items()):
+        print("\t%s: %d alleles" % (gene, len(alleles)), file=sys.stderr)
         for allele in alleles:
             if allele in nuc_alleles[gene]:
                 continue
@@ -110,6 +110,6 @@
                     break                    
 
             if not found:
-                print >> sys.stderr, "\t\t%s is missing" % allele
+                print("\t\t%s is missing" % allele, file=sys.stderr)
 
             
--- hisat2.orig/hisatgenotype_scripts/get_haplotype_ILMN_StrandSeq.py
+++ hisat2/hisatgenotype_scripts/get_haplotype_ILMN_StrandSeq.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2016, Daehwan Kim <infphilo@gmail.com>
@@ -65,7 +65,7 @@
         if prev_run != "" and prev_run != run:
             if len(plus) > 0 and len(minus) > 0:
                 if len(plus) > 1 or len(minus) > 1:
-                    print run_to_genome[prev_run], prev_run, plus, minus
+                    print(run_to_genome[prev_run], prev_run, plus, minus)
             plus, minus = set(), set()
 
         prev_run = run
@@ -73,7 +73,7 @@
     if run != "":
         if len(plus) > 0 and len(minus) > 0:
             if len(plus) > 1 or len(minus) > 1:
-                print run_to_genome[run], run, plus, minus
+                print(run_to_genome[run], run, plus, minus)
 
 
 """
--- hisat2.orig/hisatgenotype_scripts/hisatgenotype_HLA_genotyping_PGs.py
+++ hisat2/hisatgenotype_scripts/hisatgenotype_HLA_genotyping_PGs.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2015, Daehwan Kim <infphilo@gmail.com>
@@ -84,7 +84,7 @@
     ex_path = os.path.dirname(curr_script)
 
     if not os.path.exists("illumina/HLA"):
-        print >> sys.stderr, "Error: illumina/HLA data is needed (please send an email to infphilo@gmail.com for getting the data)"
+        print("Error: illumina/HLA data is needed (please send an email to infphilo@gmail.com for getting the data)", file=sys.stderr)
         sys.exit(1)
 
     num_test, num_success = 0, 0
@@ -95,14 +95,14 @@
         read_fname_1, read_fname_2 = "illumina/HLA/%s.fished_1.fq" % genome, "illumina/HLA/%s.fished_2.fq" % genome
         if not os.path.exists(read_fname_1) or not os.path.exists(read_fname_2):
             continue
-        print >> sys.stderr, genome        
+        print(genome, file=sys.stderr)        
         cmd_aligners = ['.'.join(aligners[i]) for i in range(len(aligners))]
         test_hla_script = os.path.join(ex_path, "hisat2_test_HLA_genotyping.py")
         for gene in sorted(genes.keys()):
             if not gene in hla_list:
                 continue
             alleles = genes[gene]
-            print >> sys.stderr, "\t%s - %s" % (gene, ' / '.join(alleles))            
+            print("\t%s - %s" % (gene, ' / '.join(alleles)), file=sys.stderr)            
             test_hla_cmd = [test_hla_script,
                             "--reference-type", reference_type,
                             "--hla-list", gene,
@@ -113,13 +113,13 @@
                             "--num-mismatch", str(num_mismatch)]
 
             if verbose:
-                print >> sys.stderr, ' '.join(test_hla_cmd)
+                print(' '.join(test_hla_cmd), file=sys.stderr)
             
             proc = subprocess.Popen(test_hla_cmd, stdout=subprocess.PIPE, stderr=open("/dev/null", 'w'))
             num_test += 2
             test_alleles = set()
             for line in proc.stdout:
-                print "\t\t", line,
+                print("\t\t", line, end=' ')
                 model, allele = line.split()[:2]
                 if model != "SingleModel":
                     continue
@@ -131,7 +131,7 @@
                 if allele in test_alleles:
                     num_success += 1
 
-    print >> sys.stderr, "%d/%d (%.2f%%)" % (num_success, num_test, num_success * 100.0 / num_test)
+    print("%d/%d (%.2f%%)" % (num_success, num_test, num_success * 100.0 / num_test), file=sys.stderr)
 
 
 """
@@ -154,7 +154,7 @@
                         type=str,
                         default="hisat2.graph",
                         help="A comma-separated list of aligners (default: hisat2.graph)")
-    genomes_default = ','.join(gold_allele_info.keys())
+    genomes_default = ','.join(list(gold_allele_info.keys()))
     parser.add_argument("--genome-list",
                         dest="genome_list",
                         type=str,
@@ -178,11 +178,11 @@
     args = parser.parse_args()
 
     if not args.reference_type in ["gene", "chromosome", "genome"]:
-        print >> sys.stderr, "Error: --reference-type (%s) must be one of gene, chromosome, and genome." % (args.reference_type)
+        print("Error: --reference-type (%s) must be one of gene, chromosome, and genome." % (args.reference_type), file=sys.stderr)
         sys.exit(1)
     args.hla_list = args.hla_list.split(',')
     if args.aligners == "":
-        print >> sys.stderr, "Error: --aligners must be non-empty."
+        print("Error: --aligners must be non-empty.", file=sys.stderr)
         sys.exit(1)    
     args.aligners = args.aligners.split(',')
     for i in range(len(args.aligners)):
--- hisat2.orig/hisatgenotype_scripts/hisatgenotype_locus_samples.py
+++ hisat2/hisatgenotype_scripts/hisatgenotype_locus_samples.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Copyright 2015, Daehwan Kim <infphilo@gmail.com>
@@ -95,10 +95,10 @@
     if not os.path.exists(read_fname_1) or not os.path.exists(read_fname_2):
         return
     lock.acquire()
-    print >> sys.stderr, genome
+    print(genome, file=sys.stderr)
     lock.release()
 
-    for family, loci in region_list.items():
+    for family, loci in list(region_list.items()):
         test_hla_cmd = ["hisatgenotype_locus.py",
                         "--base", family]
         if len(loci) > 0:
@@ -115,7 +115,7 @@
 
         if verbose:
             lock.acquire()
-            print >> sys.stderr, ' '.join(test_hla_cmd)
+            print(' '.join(test_hla_cmd), file=sys.stderr)
             lock.release()
 
         proc = subprocess.Popen(test_hla_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
@@ -132,7 +132,7 @@
     lock.acquire()
     for output in output_list:
         allele, abundance = output
-        print >> sys.stdout, "%s\t%s\t%s" % (genome, allele, abundance)
+        print("%s\t%s\t%s" % (genome, allele, abundance), file=sys.stdout)
     sys.stdout.flush()
     lock.release()
 
@@ -160,7 +160,7 @@
                                                 verbose)
     
     if not os.path.exists(read_dir):
-        print >> sys.stderr, "Error: %s does not exist." % read_dir
+        print("Error: %s does not exist." % read_dir, file=sys.stderr)
         sys.exit(1)
 
     if out_dir != "" and not os.path.exists(out_dir):
@@ -225,7 +225,7 @@
     parser.add_argument("--max-sample",
                         dest="max_sample",
                         type=int,
-                        default=sys.maxint,
+                        default=sys.maxsize,
                         help="Number of samples to be analyzed (default: sys.maxint)")
     parser.add_argument("--out-dir",
                         dest="out_dir",
@@ -240,11 +240,11 @@
     args = parser.parse_args()
 
     if args.read_dir == "":
-        print >> sys.stderr, "Error: please specify --read-dir."
+        print("Error: please specify --read-dir.", file=sys.stderr)
         sys.exit(1)
 
     if not args.reference_type in ["gene", "chromosome", "genome"]:
-        print >> sys.stderr, "Error: --reference-type (%s) must be one of gene, chromosome, and genome." % (args.reference_type)
+        print("Error: --reference-type (%s) must be one of gene, chromosome, and genome." % (args.reference_type), file=sys.stderr)
         sys.exit(1)
 
     region_list = {}
@@ -252,7 +252,7 @@
         for region in args.region_list.split(','):
             region = region.split('.')
             if len(region) < 1 or len(region) > 2:
-                print >> sys.stderr, "Error: --region-list is incorrectly formatted."
+                print("Error: --region-list is incorrectly formatted.", file=sys.stderr)
                 sys.exit(1)
                 
             family = region[0].lower()
--- hisat2.orig/hisatgenotype_modules/hisatgenotype_gene_typing.py
+++ hisat2/hisatgenotype_modules/hisatgenotype_gene_typing.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 import sys, os
 import math
--- hisat2.orig/hisat2-build
+++ hisat2/hisat2-build
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
  Copyright 2015, Daehwan Kim <infphilo@gmail.com>
--- hisat2.orig/hisat2-inspect
+++ hisat2/hisat2-inspect
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
  Copyright 2015, Daehwan Kim <infphilo@gmail.com>
