aboutsummaryrefslogtreecommitdiff
path: root/biology/groopm/files/patch-2to3
diff options
context:
space:
mode:
Diffstat (limited to 'biology/groopm/files/patch-2to3')
-rw-r--r--biology/groopm/files/patch-2to33414
1 files changed, 3414 insertions, 0 deletions
diff --git a/biology/groopm/files/patch-2to3 b/biology/groopm/files/patch-2to3
new file mode 100644
index 000000000000..365000a5d096
--- /dev/null
+++ b/biology/groopm/files/patch-2to3
@@ -0,0 +1,3414 @@
+--- groopm/PCA.py.orig 2014-11-26 01:01:33 UTC
++++ groopm/PCA.py
+@@ -79,7 +79,7 @@ class PCA:
+ try:
+ self.sumvariance /= self.sumvariance[-1]
+ except:
+- print len(A), len(self.sumvariance), len(self.eigen)
++ print(len(A), len(self.sumvariance), len(self.eigen))
+ raise
+
+ self.npc = np.searchsorted( self.sumvariance, fraction ) + 1
+@@ -127,13 +127,13 @@ class Center:
+ def __init__( self, A, axis=0, scale=True, verbose=1 ):
+ self.mean = A.mean(axis=axis)
+ if verbose:
+- print "Center -= A.mean:", self.mean
++ print("Center -= A.mean:", self.mean)
+ A -= self.mean
+ if scale:
+ std = A.std(axis=axis)
+ self.std = np.where( std, std, 1. )
+ if verbose:
+- print "Center /= A.std:", self.std
++ print("Center /= A.std:", self.std)
+ A /= self.std
+ else:
+ self.std = np.ones( A.shape[-1] )
+--- groopm/bin.py.orig 2015-03-06 07:01:36 UTC
++++ groopm/bin.py
+@@ -59,8 +59,8 @@ from numpy import (around as np_around,
+ median as np_median,
+ std as np_std)
+
+-from ellipsoid import EllipsoidTool
+-from groopmExceptions import ModeNotAppropriateException
++from .ellipsoid import EllipsoidTool
++from .groopmExceptions import ModeNotAppropriateException
+
+ np.seterr(all='raise')
+
+@@ -155,7 +155,7 @@ class Bin:
+ """Combine the contigs of another bin with this one"""
+ # consume all the other bins rowIndices
+ if(verbose):
+- print " BIN:",deadBin.id,"will be consumed by BIN:",self.id
++ print(" BIN:",deadBin.id,"will be consumed by BIN:",self.id)
+ self.rowIndices = np.concatenate([self.rowIndices, deadBin.rowIndices])
+ self.binSize = self.rowIndices.shape[0]
+
+@@ -326,7 +326,7 @@ class Bin:
+ try:
+ return ET.getMinVolEllipse(bin_points, retA=retA)
+ except:
+- print bin_points
++ print(bin_points)
+ raise
+ else: # minimum bounding ellipse of a point is 0
+ if retA:
+@@ -474,13 +474,13 @@ class Bin:
+ fig.set_size_inches(10,4)
+ plt.savefig(fileName,dpi=300)
+ except:
+- print "Error saving image:", fileName, sys.exc_info()[0]
++ print("Error saving image:", fileName, sys.exc_info()[0])
+ raise
+ else:
+ try:
+ plt.show()
+ except:
+- print "Error showing image:", sys.exc_info()[0]
++ print("Error showing image:", sys.exc_info()[0])
+ raise
+ del fig
+
+@@ -504,13 +504,13 @@ class Bin:
+ fig.set_size_inches(6,6)
+ plt.savefig(fileName+".png",dpi=300)
+ except:
+- print "Error saving image:", fileName, sys.exc_info()[0]
++ print("Error saving image:", fileName, sys.exc_info()[0])
+ raise
+ elif(show):
+ try:
+ plt.show()
+ except:
+- print "Error showing image:", sys.exc_info()[0]
++ print("Error showing image:", sys.exc_info()[0])
+ raise
+ plt.close(fig)
+ del fig
+@@ -636,8 +636,8 @@ class Bin:
+
+ If you pass through an EllipsoidTool then it will plot the minimum bounding ellipse as well!
+ """
+- disp_vals = np.array(zip([kPCA1[i] for i in self.rowIndices],
+- [kPCA2[i] for i in self.rowIndices]))
++ disp_vals = np.array(list(zip([kPCA1[i] for i in self.rowIndices],
++ [kPCA2[i] for i in self.rowIndices])))
+ disp_lens = np.array([np.sqrt(contigLengths[i]) for i in self.rowIndices])
+
+ # reshape
+@@ -695,7 +695,7 @@ class Bin:
+ data = [str(self.id), str(isLikelyChimeric[self.id]), str(self.totalBP), str(self.binSize), gcm_str, gcs_str]
+ cov_mean = np.mean(covProfiles[self.rowIndices], axis=0)
+ cov_std = np.std(covProfiles[self.rowIndices], axis=0)
+- for i in xrange(0, len(cov_mean)):
++ for i in range(0, len(cov_mean)):
+ data.append('%.4f' % cov_mean[i])
+ data.append('%.4f' % cov_std[i])
+ stream.write(separator.join(data)+"\n")
+--- groopm/binManager.py.orig 2015-03-06 07:02:49 UTC
++++ groopm/binManager.py
+@@ -85,11 +85,11 @@ from scipy.stats import f_oneway, distributions
+ from scipy.cluster.vq import kmeans,vq
+
+ # GroopM imports
+-from profileManager import ProfileManager
+-from bin import Bin, mungeCbar
+-import groopmExceptions as ge
+-from groopmUtils import makeSurePathExists
+-from ellipsoid import EllipsoidTool
++from .profileManager import ProfileManager
++from .bin import Bin, mungeCbar
++from . import groopmExceptions as ge
++from .groopmUtils import makeSurePathExists
++from .ellipsoid import EllipsoidTool
+
+ np_seterr(all='raise')
+
+@@ -182,15 +182,15 @@ class BinManager:
+ if self.PM.numStoits == 3:
+ self.PM.transformedCP = self.PM.covProfiles
+ else:
+- print "Number of stoits != 3. You need to transform"
++ print("Number of stoits != 3. You need to transform")
+ self.PM.transformCP(timer, silent=silent)
+ if not silent:
+- print " Making bin objects"
++ print(" Making bin objects")
+ self.makeBins(self.getBinMembers())
+ if not silent:
+- print " Loaded %d bins from database" % len(self.bins)
++ print(" Loaded %d bins from database" % len(self.bins))
+ if not silent:
+- print " %s" % timer.getTimeStamp()
++ print(" %s" % timer.getTimeStamp())
+ sys_stdout.flush()
+
+ def getBinMembers(self):
+@@ -210,7 +210,7 @@ class BinManager:
+
+ # we need to get the largest BinId in use
+ if len(bin_members) > 0:
+- self.nextFreeBinId = np_max(bin_members.keys())
++ self.nextFreeBinId = np_max(list(bin_members.keys()))
+ return bin_members
+
+ def makeBins(self, binMembers, zeroIsBin=False):
+@@ -224,8 +224,8 @@ class BinManager:
+ self.bins[bid] = Bin(np_array(binMembers[bid]), bid, self.PM.scaleFactor-1)
+ self.bins[bid].makeBinDist(self.PM.transformedCP, self.PM.averageCoverages, self.PM.kmerNormPC1, self.PM.kmerPCs, self.PM.contigGCs, self.PM.contigLengths)
+ if len(invalid_bids) != 0:
+- print "MT bins!"
+- print invalid_bids
++ print("MT bins!")
++ print(invalid_bids)
+ exit(-1)
+
+ def saveBins(self, binAssignments={}, nuke=False):
+@@ -384,7 +384,7 @@ class BinManager:
+ all_links[key] = links[link]
+
+ # sort and return
+- return sorted(all_links.iteritems(), key=itemgetter(1), reverse=True)
++ return sorted(iter(all_links.items()), key=itemgetter(1), reverse=True)
+
+ def getWithinLinkProfiles(self):
+ """Determine the average number of links between contigs for all bins"""
+@@ -468,7 +468,7 @@ class BinManager:
+ (bin_assignment_update, bids) = self.getSplitties(bid, n, mode)
+
+ if(auto and saveBins):
+- print 'here!!!!'
++ print('here!!!!')
+ # charge on through
+ self.deleteBins([bids[0]], force=True) # delete the combined bin
+ # save new bins
+@@ -536,12 +536,12 @@ class BinManager:
+ parts = 0
+ while(not_got_parts):
+ try:
+- parts = int(raw_input("Enter new number of parts:"))
++ parts = int(input("Enter new number of parts:"))
+ except ValueError:
+- print "You need to enter an integer value!"
++ print("You need to enter an integer value!")
+ parts = 0
+ if(1 == parts):
+- print "Don't be a silly sausage!"
++ print("Don't be a silly sausage!")
+ elif(0 != parts):
+ not_got_parts = False
+ self.split(bid,
+@@ -664,7 +664,7 @@ class BinManager:
+ F_cutoff = distributions.f.ppf(confidence, 2, len(dist1)+len(dist2)-2)
+ F_value = f_oneway(dist1,dist2)[0]
+ if tag != "":
+- print "%s [V: %f, C: %f]" % (tag, F_value, F_cutoff)
++ print("%s [V: %f, C: %f]" % (tag, F_value, F_cutoff))
+ return F_value < F_cutoff
+
+ def merge(self, bids, auto=False, manual=False, newBid=False, saveBins=False, verbose=False, printInstructions=True, use_elipses=True):
+@@ -715,11 +715,11 @@ class BinManager:
+ self.deleteBins([tmp_bin.id], force=True)
+ user_option = self.promptOnMerge(bids=[parent_bin.id,dead_bin.id])
+ if(user_option == "N"):
+- print "Merge skipped"
++ print("Merge skipped")
+ ret_val = 1
+ continue_merge=False
+ elif(user_option == "Q"):
+- print "All mergers skipped"
++ print("All mergers skipped")
+ return 0
+ else:
+ ret_val = 2
+@@ -799,7 +799,7 @@ class BinManager:
+ try:
+ del self.PM.binnedRowIndices[row_index]
+ except KeyError:
+- print bid, row_index, "FUNG"
++ print(bid, row_index, "FUNG")
+ self.PM.binIds[row_index] = 0
+
+ bin_assignment_update[row_index] = 0
+@@ -826,7 +826,7 @@ class BinManager:
+ # UI
+
+ def printMergeInstructions(self):
+- raw_input( "****************************************************************\n"
++ input( "****************************************************************\n"
+ " MERGING INSTRUCTIONS - PLEASE READ CAREFULLY\n"
+ "****************************************************************\n"
+ " The computer cannot always be trusted to perform bin mergers\n"
+@@ -836,10 +836,10 @@ class BinManager:
+ " to continue with the merging operation.\n"
+ " The image on the far right shows the bins after merging\n"
+ " Press any key to produce plots...")
+- print "****************************************************************"
++ print("****************************************************************")
+
+ def printSplitInstructions(self):
+- raw_input( "****************************************************************\n"
++ input( "****************************************************************\n"
+ " SPLITTING INSTRUCTIONS - PLEASE READ CAREFULLY\n"
+ "****************************************************************\n"
+ " The computer cannot always be trusted to perform bin splits\n"
+@@ -848,7 +848,7 @@ class BinManager:
+ " be split. Look carefully at each plot and then close the plot\n"
+ " to continue with the splitting operation.\n\n"
+ " Press any key to produce plots...")
+- print "****************************************************************"
++ print("****************************************************************")
+
+ def getPlotterMergeIds(self):
+ """Prompt the user for ids to be merged and check that it's all good"""
+@@ -856,7 +856,7 @@ class BinManager:
+ ret_bids = []
+ while(input_not_ok):
+ ret_bids = []
+- option = raw_input("Please enter 'space' separated bin Ids or 'q' to quit: ")
++ option = input("Please enter 'space' separated bin Ids or 'q' to quit: ")
+ if(option.upper() == 'Q'):
+ return []
+ bids = option.split(" ")
+@@ -866,13 +866,13 @@ class BinManager:
+ i_bid = int(bid)
+ # check that it's in the bins list
+ if(i_bid not in self.bins):
+- print "**Error: bin",bid,"not found"
++ print("**Error: bin",bid,"not found")
+ input_not_ok = True
+ break
+ input_not_ok = False
+ ret_bids.append(i_bid)
+ except ValueError:
+- print "**Error: invalid value:", bid
++ print("**Error: invalid value:", bid)
+ input_not_ok = True
+ break
+ return ret_bids
+@@ -889,19 +889,19 @@ class BinManager:
+ bin_str += " and "+str(bids[i])
+ while(input_not_ok):
+ if(minimal):
+- option = raw_input(" Merge? ("+vrs+") : ")
++ option = input(" Merge? ("+vrs+") : ")
+ else:
+- option = raw_input(" ****WARNING**** About to merge bins"+bin_str+"\n" \
++ option = input(" ****WARNING**** About to merge bins"+bin_str+"\n" \
+ " If you continue you *WILL* overwrite existing bins!\n" \
+ " You have been shown a 3d plot of the bins to be merged.\n" \
+ " Continue only if you're sure this is what you want to do!\n" \
+ " y = yes, n = no, q = no and quit merging\n" \
+ " Merge? ("+vrs+") : ")
+ if(option.upper() in valid_responses):
+- print "****************************************************************"
++ print("****************************************************************")
+ return option.upper()
+ else:
+- print "Error, unrecognised choice '"+option.upper()+"'"
++ print("Error, unrecognised choice '"+option.upper()+"'")
+ minimal = True
+
+ def promptOnSplit(self, parts, mode, minimal=False):
+@@ -911,9 +911,9 @@ class BinManager:
+ vrs = ",".join([str.lower(str(x)) for x in valid_responses])
+ while(input_not_ok):
+ if(minimal):
+- option = raw_input(" Split? ("+vrs+") : ")
++ option = input(" Split? ("+vrs+") : ")
+ else:
+- option = raw_input(" ****WARNING**** About to split bin into "+str(parts)+" parts\n" \
++ option = input(" ****WARNING**** About to split bin into "+str(parts)+" parts\n" \
+ " If you continue you *WILL* overwrite existing bins!\n" \
+ " You have been shown a 3d plot of the bin after splitting.\n" \
+ " Continue only if you're sure this is what you want to do!\n" \
+@@ -923,13 +923,13 @@ class BinManager:
+ " Split? ("+vrs+") : ")
+ if(option.upper() in valid_responses):
+ if(option.upper() == 'K' and mode.upper() == 'KMER' or option.upper() == 'C' and mode.upper() == 'COV' or option.upper() == 'L' and mode.upper() == 'LEN'):
+- print "Error, you are already using that profile to split!"
++ print("Error, you are already using that profile to split!")
+ minimal=True
+ else:
+- print "****************************************************************"
++ print("****************************************************************")
+ return option.upper()
+ else:
+- print "Error, unrecognised choice '"+option.upper()+"'"
++ print("Error, unrecognised choice '"+option.upper()+"'")
+ minimal = True
+
+ def promptOnDelete(self, bids, minimal=False):
+@@ -940,19 +940,19 @@ class BinManager:
+ bids_str = ",".join([str.lower(str(x)) for x in bids])
+ while(input_not_ok):
+ if(minimal):
+- option = raw_input(" Delete? ("+vrs+") : ")
++ option = input(" Delete? ("+vrs+") : ")
+ else:
+- option = raw_input(" ****WARNING**** About to delete bin(s):\n" \
++ option = input(" ****WARNING**** About to delete bin(s):\n" \
+ " "+bids_str+"\n" \
+ " If you continue you *WILL* overwrite existing bins!\n" \
+ " Continue only if you're sure this is what you want to do!\n" \
+ " y = yes, n = no\n"\
+ " Delete? ("+vrs+") : ")
+ if(option.upper() in valid_responses):
+- print "****************************************************************"
++ print("****************************************************************")
+ return option.upper()
+ else:
+- print "Error, unrecognised choice '"+option.upper()+"'"
++ print("Error, unrecognised choice '"+option.upper()+"'")
+ minimal = True
+
+ #------------------------------------------------------------------------------
+@@ -1039,10 +1039,10 @@ class BinManager:
+
+ # find the mean and stdev
+ if(not makeKillList):
+- return (np_mean(np_array(Ms.values())), np_std(np_array(Ms.values())), np_median(np_array(Ss.values())), np_std(np_array(Ss.values())))
++ return (np_mean(np_array(list(Ms.values()))), np_std(np_array(list(Ms.values()))), np_median(np_array(list(Ss.values()))), np_std(np_array(list(Ss.values()))))
+
+ else:
+- cutoff = np_mean(np_array(Ms.values())) + tolerance * np_std(np_array(Ms.values()))
++ cutoff = np_mean(np_array(list(Ms.values()))) + tolerance * np_std(np_array(list(Ms.values())))
+ kill_list = []
+ for bid in Ms:
+ if(Ms[bid] > cutoff):
+@@ -1054,7 +1054,7 @@ class BinManager:
+
+ return a list of potentially confounding kmer indices
+ """
+- print " Measuring kmer type variances"
++ print(" Measuring kmer type variances")
+ means = np_array([])
+ stdevs = np_array([])
+ bids = np_array([])
+@@ -1094,12 +1094,12 @@ class BinManager:
+ return_indices.append(sort_within_indices[i])
+
+ if(plot):
+- print "BETWEEN"
++ print("BETWEEN")
+ for i in range(0,number_to_trim):
+- print names[sort_between_indices[i]]
+- print "WITHIN"
++ print(names[sort_between_indices[i]])
++ print("WITHIN")
+ for i in range(0,number_to_trim):
+- print names[sort_within_indices[i]]
++ print(names[sort_within_indices[i]])
+
+ plt.figure(1)
+ plt.subplot(211)
+@@ -1126,7 +1126,7 @@ class BinManager:
+ stdout = open(fileName, 'w')
+ self.printInner(outFormat, stdout)
+ except:
+- print "Error diverting stout to file:", fileName, exc_info()[0]
++ print("Error diverting stout to file:", fileName, exc_info()[0])
+ raise
+ else:
+ self.printInner(outFormat)
+@@ -1139,14 +1139,14 @@ class BinManager:
+ stream.write(separator.join(["#\"bid\"","\"cid\"","\"length\"","\"GC\""])+"\n")
+ elif(outFormat == 'bins'):
+ header = ["\"bin id\"","\"Likely chimeric\"","\"length (bp)\"","\"# seqs\"","\"GC mean\"","\"GC std\""]
+- for i in xrange(0, len(self.PM.covProfiles[0])):
++ for i in range(0, len(self.PM.covProfiles[0])):
+ header.append("\"Coverage " + str(i+1) + " mean\"")
+ header.append("\"Coverage " + str(i+1) + " std\"")
+ stream.write(separator.join(header) + "\n")
+ elif(outFormat == 'full'):
+ pass
+ else:
+- print "Error: Unrecognised format:", outFormat
++ print("Error: Unrecognised format:", outFormat)
+ return
+
+ for bid in self.getBids():
+@@ -1224,13 +1224,13 @@ class BinManager:
+ try:
+ plt.savefig(fileName,dpi=300)
+ except:
+- print "Error saving image:", fileName, exc_info()[0]
++ print("Error saving image:", fileName, exc_info()[0])
+ raise
+ else:
+ try:
+ plt.show()
+ except:
+- print "Error showing image:", exc_info()[0]
++ print("Error showing image:", exc_info()[0])
+ raise
+
+ plt.close(fig)
+@@ -1344,7 +1344,7 @@ class BinManager:
+ try:
+ plt.show()
+ except:
+- print "Error showing image:", exc_info()[0]
++ print("Error showing image:", exc_info()[0])
+ raise
+
+ plt.close(fig)
+@@ -1369,10 +1369,10 @@ class BinManager:
+ self.bins[bid].makeBinDist(self.PM.transformedCP, self.PM.averageCoverages, self.PM.kmerNormPC1, self.PM.kmerPCs, self.PM.contigGCs, self.PM.contigLengths)
+
+ if(sideBySide):
+- print "Plotting side by side"
+- self.plotSideBySide(self.bins.keys(), tag=FNPrefix, ignoreContigLengths=ignoreContigLengths)
++ print("Plotting side by side")
++ self.plotSideBySide(list(self.bins.keys()), tag=FNPrefix, ignoreContigLengths=ignoreContigLengths)
+ else:
+- print "Plotting bins"
++ print("Plotting bins")
+ for bid in self.getBids():
+ if folder != '':
+ self.bins[bid].plotBin(self.PM.transformedCP, self.PM.contigGCs, self.PM.kmerNormPC1,
+@@ -1387,7 +1387,7 @@ class BinManager:
+ def plotBinCoverage(self, plotEllipses=False, plotContigLengs=False, printID=False):
+ """Make plots of all the bins"""
+
+- print "Plotting first 3 stoits in untransformed coverage space"
++ print("Plotting first 3 stoits in untransformed coverage space")
+
+ # plot contigs in coverage space
+ fig = plt.figure()
+@@ -1452,7 +1452,7 @@ class BinManager:
+ plt.show()
+ plt.close(fig)
+ except:
+- print "Error showing image", exc_info()[0]
++ print("Error showing image", exc_info()[0])
+ raise
+
+ del fig
+@@ -1504,13 +1504,13 @@ class BinManager:
+ fig.set_size_inches(12,6)
+ plt.savefig(fileName,dpi=300)
+ except:
+- print "Error saving image:", fileName, exc_info()[0]
++ print("Error saving image:", fileName, exc_info()[0])
+ raise
+ elif(show):
+ try:
+ plt.show()
+ except:
+- print "Error showing image:", exc_info()[0]
++ print("Error showing image:", exc_info()[0])
+ raise
+ plt.close(fig)
+ del fig
+@@ -1554,7 +1554,7 @@ class BinManager:
+ plt.show()
+ plt.close(fig)
+ except:
+- print "Error showing image", exc_info()[0]
++ print("Error showing image", exc_info()[0])
+ raise
+ del fig
+
+@@ -1563,7 +1563,7 @@ class BinManager:
+ (bin_centroid_points, _bin_centroid_colors, bin_centroid_gc, _bids) = self.findCoreCentres(processChimeric=showChimeric)
+ fig = plt.figure()
+ ax = fig.add_subplot(111, projection='3d')
+- print bin_centroid_gc
++ print(bin_centroid_gc)
+ sc = ax.scatter(bin_centroid_points[:,0], bin_centroid_points[:,1], bin_centroid_points[:,2], edgecolors='k', c=bin_centroid_gc, cmap=self.PM.colorMapGC, vmin=0.0, vmax=1.0)
+ sc.set_edgecolors = sc.set_facecolors = lambda *args:None # disable depth transparency effect
+
+@@ -1588,7 +1588,7 @@ class BinManager:
+ plt.show()
+ plt.close(fig)
+ except:
+- print "Error showing image", exc_info()[0]
++ print("Error showing image", exc_info()[0])
+ raise
+ del fig
+
+--- groopm/cluster.py.orig 2015-03-06 04:42:51 UTC
++++ groopm/cluster.py
+@@ -95,11 +95,11 @@ from scipy.spatial.distance import pdist, squareform,
+ from scipy.misc import imsave
+
+ # GroopM imports
+-from profileManager import ProfileManager
+-from binManager import BinManager
+-from refine import GrubbsTester, RefineEngine
+-from PCA import PCA, Center
+-from groopmExceptions import BinNotFoundException
++from .profileManager import ProfileManager
++from .binManager import BinManager
++from .refine import GrubbsTester, RefineEngine
++from .PCA import PCA, Center
++from .groopmExceptions import BinNotFoundException
+
+ np_seterr(all='raise')
+
+@@ -160,22 +160,22 @@ class ClusterEngine:
+ vrs = ",".join([str.lower(str(x)) for x in valid_responses])
+ while(input_not_ok):
+ if(minimal):
+- option = raw_input(" Overwrite? ("+vrs+") : ")
++ option = input(" Overwrite? ("+vrs+") : ")
+ else:
+- option = raw_input(" ****WARNING**** Database: '"+self.PM.dbFileName+"' has already been clustered.\n" \
++ option = input(" ****WARNING**** Database: '"+self.PM.dbFileName+"' has already been clustered.\n" \
+ " If you continue you *MAY* overwrite existing bins!\n" \
+ " Overwrite? ("+vrs+") : ")
+ if(option.upper() in valid_responses):
+- print "****************************************************************"
++ print("****************************************************************")
+ if(option.upper() == "N"):
+- print "Operation cancelled"
++ print("Operation cancelled")
+ return False
+ else:
+ break
+ else:
+- print "Error, unrecognised choice '"+option.upper()+"'"
++ print("Error, unrecognised choice '"+option.upper()+"'")
+ minimal = True
+- print "Will Overwrite database",self.PM.dbFileName
++ print("Will Overwrite database",self.PM.dbFileName)
+ return True
+
+ #------------------------------------------------------------------------------
+@@ -189,10 +189,10 @@ class ClusterEngine:
+
+ # get some data
+ self.PM.loadData(self.timer, "length >= "+str(coreCut))
+- print " %s" % self.timer.getTimeStamp()
++ print(" %s" % self.timer.getTimeStamp())
+
+ # transform the data
+- print " Loading transformed data"
++ print(" Loading transformed data")
+ self.PM.transformCP(self.timer)
+ # plot the transformed space (if we've been asked to...)
+ #if(self.debugPlots >= 3):
+@@ -201,15 +201,15 @@ class ClusterEngine:
+ # now we can make this guy
+ self.TSpan = np_mean([np_norm(self.PM.corners[i] - self.PM.TCentre) for i in range(self.PM.numStoits)])
+
+- print " %s" % self.timer.getTimeStamp()
++ print(" %s" % self.timer.getTimeStamp())
+
+ # cluster and bin!
+- print "Create cores"
++ print("Create cores")
+ self.initialiseCores(kmerThreshold, coverageThreshold)
+- print " %s" % self.timer.getTimeStamp()
++ print(" %s" % self.timer.getTimeStamp())
+
+ # condense cores
+- print "Refine cores [begin: %d]" % len(self.BM.bins)
++ print("Refine cores [begin: %d]" % len(self.BM.bins))
+ if self.finalPlot:
+ prfx = "CORE"
+ else:
+@@ -217,9 +217,9 @@ class ClusterEngine:
+ self.RE.refineBins(self.timer, auto=True, saveBins=False, plotFinal=prfx, gf=gf)
+
+ # Now save all the stuff to disk!
+- print "Saving bins"
++ print("Saving bins")
+ self.BM.saveBins(nuke=True)
+- print " %s" % self.timer.getTimeStamp()
++ print(" %s" % self.timer.getTimeStamp())
+
+ def initialiseCores(self, kmerThreshold, coverageThreshold):
+ """Process contigs and form CORE bins"""
+@@ -230,8 +230,8 @@ class ClusterEngine:
+ # We can make a heat map and look for hot spots
+ self.populateImageMaps()
+ sub_counter = 0
+- print " .... .... .... .... .... .... .... .... .... ...."
+- print "%4d" % sub_counter,
++ print(" .... .... .... .... .... .... .... .... .... ....")
++ print("%4d" % sub_counter, end=' ')
+ new_line_counter = 0
+ num_bins = 0
+
+@@ -303,13 +303,13 @@ class ClusterEngine:
+ self.updatePostBin(bin)
+
+ new_line_counter += 1
+- print "% 4d" % bin.binSize,
++ print("% 4d" % bin.binSize, end=' ')
+
+ # make the printing prettier
+ if(new_line_counter > 9):
+ new_line_counter = 0
+ sub_counter += 10
+- print "\n%4d" % sub_counter,
++ print("\n%4d" % sub_counter, end=' ')
+
+ if(self.debugPlots >= 1):
+ #***slow plot!
+@@ -317,7 +317,7 @@ class ClusterEngine:
+
+ except BinNotFoundException: pass
+
+- print "\n .... .... .... .... .... .... .... .... .... ...."
++ print("\n .... .... .... .... .... .... .... .... .... ....")
+
+ def findNewClusterCenters(self, kmerThreshold, coverageThreshold):
+ """Find a putative cluster"""
+@@ -498,32 +498,32 @@ class ClusterEngine:
+ k_dist_matrix = squareform(pdist(k_dat, 'cityblock'))
+ k_radius = np_median(np_sort(k_dist_matrix)[:,eps_neighbours])
+ except MemoryError:
+- print "\n"
+- print '*******************************************************************************'
+- print '********************************* ERROR *********************************'
+- print '*******************************************************************************'
+- print 'GroopM is attempting to do some maths on a putative bin which contains:'
+- print
+- print '\t\t%d contigs' % (len(rowIndices))
+- print
+- print 'This has caused your machine to run out of memory.'
+- print 'The most likely cause is that your samples are very different from each other.'
+- print 'You can confirm this by running:'
+- print
+- print '\t\tgroopm explore -m allcontigs %s' % self.PM.dbFileName
+- print
+- print 'If you notice only vertical "spears" of contigs at the corners of the plot then'
+- print 'this means that your samples are very different and you are not getting a good'
+- print 'mapping from all samples to all contigs. You may get more mileage by assembling'
+- print 'and binning your samples separately.'
+- print
+- print 'If you notice "clouds" of contigs then congratulations! You have found a bug.'
+- print 'Please let me know at "%s or via github.com/minillinim/GroopM' % __email__
+- print
+- print 'GroopM is aborting... sorry'
+- print
+- print '*******************************************************************************'
+- print "\n"
++ print("\n")
++ print('*******************************************************************************')
++ print('********************************* ERROR *********************************')
++ print('*******************************************************************************')
++ print('GroopM is attempting to do some maths on a putative bin which contains:')
++ print()
++ print('\t\t%d contigs' % (len(rowIndices)))
++ print()
++ print('This has caused your machine to run out of memory.')
++ print('The most likely cause is that your samples are very different from each other.')
++ print('You can confirm this by running:')
++ print()
++ print('\t\tgroopm explore -m allcontigs %s' % self.PM.dbFileName)
++ print()
++ print('If you notice only vertical "spears" of contigs at the corners of the plot then')
++ print('this means that your samples are very different and you are not getting a good')
++ print('mapping from all samples to all contigs. You may get more mileage by assembling')
++ print('and binning your samples separately.')
++ print()
++ print('If you notice "clouds" of contigs then congratulations! You have found a bug.')
++ print('Please let me know at "%s or via github.com/minillinim/GroopM' % __email__)
++ print()
++ print('GroopM is aborting... sorry')
++ print()
++ print('*******************************************************************************')
++ print("\n")
+ exit(-1)
+
+ # find nearest neighbours to each point in whitened coverage space,
+@@ -1341,7 +1341,7 @@ class HoughPartitioner:
+ diffs *= (len(diffs)-1)
+
+ # make it 2D
+- t_data = np_array(zip(diffs, np_arange(d_len)))
++ t_data = np_array(list(zip(diffs, np_arange(d_len))))
+ ###MMM FIX
+ #im_shape = (int(np_max(t_data, axis=0)[0]+1), d_len)
+ im_shape = (d_len, d_len)
+@@ -1532,7 +1532,7 @@ class HoughPartitioner:
+ if imgTag is not None:
+ # make a pretty picture
+ fff = np_ones(imShape) * 255
+- for p in found_line.keys():
++ for p in list(found_line.keys()):
+ fff[p[0],p[1]] = 220
+ for p in tData:
+ fff[p[0],p[1]] = 0
+@@ -1573,7 +1573,7 @@ class HoughPartitioner:
+ if real_index not in assigned:
+ tmp[real_index] = None
+ assigned[real_index] = None
+- centre = np_array(tmp.keys())
++ centre = np_array(list(tmp.keys()))
+ if len(centre) > 0:
+ return np_array([centre])
+ # nuffin
+@@ -1593,7 +1593,7 @@ class HoughPartitioner:
+ if real_index not in assigned:
+ tmp[real_index] = None
+ assigned[real_index] = None
+- centre = np_array(tmp.keys())
++ centre = np_array(list(tmp.keys()))
+
+ rets = []
+
+@@ -1609,8 +1609,8 @@ class HoughPartitioner:
+ tmp[real_index] = None
+ assigned[real_index] = None
+
+- if len(tmp.keys()) > 0:
+- rets.append(np_array(tmp.keys()))
++ if len(list(tmp.keys())) > 0:
++ rets.append(np_array(list(tmp.keys())))
+
+ else:
+ # otherwise we keep working with ranges
+@@ -1643,8 +1643,8 @@ class HoughPartitioner:
+ tmp[real_index] = None
+ assigned[real_index] = None
+
+- if len(tmp.keys()) > 0:
+- rets.append(np_array(tmp.keys()))
++ if len(list(tmp.keys())) > 0:
++ rets.append(np_array(list(tmp.keys())))
+ else:
+ right_p = self.recursiveSelect(tData,
+ imShape,
+@@ -1723,40 +1723,40 @@ class HoughPartitioner:
+ iry = half_rows + int(r/dr)
+ accumulator[iry, theta_index] -= 1
+ """
+- cos_sin_array = np_array(zip([np_sin(dth * theta_index) for theta_index in range(cols)],
+- [np_cos(dth * theta_index) for theta_index in range(cols)]))
++ cos_sin_array = np_array(list(zip([np_sin(dth * theta_index) for theta_index in range(cols)],
++ [np_cos(dth * theta_index) for theta_index in range(cols)])))
+ Rs = np_array(np_sum(np_reshape([p * cos_sin_array for p in data], (d_len*cols,2)),
+ axis=1)/dr).astype('int') + half_rows
+- Cs = np_array(range(cols)*d_len)
++ Cs = np_array(list(range(cols))*d_len)
+
+ try:
+ flat_indices = Rs * cols + Cs
+ except ValueError:
+- print "\n"
+- print '*******************************************************************************'
+- print '********************************* ERROR *********************************'
+- print '*******************************************************************************'
+- print 'GroopM is attempting to do some maths on a putative bin which contains'
+- print 'too many contigs.'
+- print
+- print 'This has resulted in a buffer overflow in the numpy library... oops.'
+- print 'The most likely cause is that your samples are very different from each other.'
+- print 'You can confirm this by running:'
+- print
+- print '\t\tgroopm explore -c 0 -m allcontigs <dbfilename>'
+- print
+- print 'If you notice only vertical "spears" of contigs at the corners of the plot then'
+- print 'this means that your samples are very different and you are not getting a good'
+- print 'mapping from all samples to all contigs. You may get more mileage by assembling'
+- print 'and binning your samples separately.'
+- print
+- print 'If you notice "clouds" of contigs then congratulations! You have found a bug.'
+- print 'Please let me know at "%s or via github.com/minillinim/GroopM' % __email__
+- print
+- print 'GroopM is aborting... sorry'
+- print
+- print '*******************************************************************************'
+- print "\n"
++ print("\n")
++ print('*******************************************************************************')
++ print('********************************* ERROR *********************************')
++ print('*******************************************************************************')
++ print('GroopM is attempting to do some maths on a putative bin which contains')
++ print('too many contigs.')
++ print()
++ print('This has resulted in a buffer overflow in the numpy library... oops.')
++ print('The most likely cause is that your samples are very different from each other.')
++ print('You can confirm this by running:')
++ print()
++ print('\t\tgroopm explore -c 0 -m allcontigs <dbfilename>')
++ print()
++ print('If you notice only vertical "spears" of contigs at the corners of the plot then')
++ print('this means that your samples are very different and you are not getting a good')
++ print('mapping from all samples to all contigs. You may get more mileage by assembling')
++ print('and binning your samples separately.')
++ print()
++ print('If you notice "clouds" of contigs then congratulations! You have found a bug.')
++ print('Please let me know at "%s or via github.com/minillinim/GroopM' % __email__)
++ print()
++ print('GroopM is aborting... sorry')
++ print()
++ print('*******************************************************************************')
++ print("\n")
+ exit(-1)
+
+ # update the accumulator with integer decrements
+--- groopm/groopm.py.orig 2014-11-26 01:01:33 UTC
++++ groopm/groopm.py
+@@ -52,14 +52,14 @@ __status__ = "Released"
+ import matplotlib as mpl
+
+ # GroopM imports
+-import mstore
+-import cluster
+-import refine
+-import binManager
+-import groopmUtils
+-import groopmTimekeeper as gtime
+-from groopmExceptions import ExtractModeNotAppropriateException
+-from mstore import GMDataManager
++from . import mstore
++from . import cluster
++from . import refine
++from . import binManager
++from . import groopmUtils
++from . import groopmTimekeeper as gtime
++from .groopmExceptions import ExtractModeNotAppropriateException
++from .mstore import GMDataManager
+
+ ###############################################################################
+ ###############################################################################
+@@ -100,12 +100,12 @@ class GroopMOptionsParser():
+ timer = gtime.TimeKeeper()
+ if(options.subparser_name == 'parse'):
+ # parse raw input
+- print "*******************************************************************************"
+- print " [[GroopM %s]] Running in data parsing mode..." % self.GMVersion
+- print "*******************************************************************************"
++ print("*******************************************************************************")
++ print(" [[GroopM %s]] Running in data parsing mode..." % self.GMVersion)
++ print("*******************************************************************************")
+ # check this here:
+ if len(options.bamfiles) < 3:
+- print "Sorry, You must supply at least 3 bamFiles to use GroopM. (You supplied %d)\n Exiting..." % len(options.bamfiles)
++ print("Sorry, You must supply at least 3 bamFiles to use GroopM. (You supplied %d)\n Exiting..." % len(options.bamfiles))
+ return
+ GMdata = mstore.GMDataManager()
+ success = GMdata.createDB(options.bamfiles,
+@@ -116,13 +116,13 @@ class GroopMOptionsParser():
+ force=options.force,
+ threads=options.threads)
+ if not success:
+- print options.dbname,"not updated"
++ print(options.dbname,"not updated")
+
+ elif(options.subparser_name == 'core'):
+ # make bin cores
+- print "*******************************************************************************"
+- print " [[GroopM %s]] Running in core creation mode..." % self.GMVersion
+- print "*******************************************************************************"
++ print("*******************************************************************************")
++ print(" [[GroopM %s]] Running in core creation mode..." % self.GMVersion)
++ print("*******************************************************************************")
+ CE = cluster.ClusterEngine(options.dbname,
+ timer,
+ force=options.force,
+@@ -139,9 +139,9 @@ class GroopMOptionsParser():
+
+ elif(options.subparser_name == 'refine'):
+ # refine bin cores
+- print "*******************************************************************************"
+- print " [[GroopM %s]] Running in core refining mode..." % self.GMVersion
+- print "*******************************************************************************"
++ print("*******************************************************************************")
++ print(" [[GroopM %s]] Running in core refining mode..." % self.GMVersion)
++ print("*******************************************************************************")
+ bids = []
+ #if options.bids is not None:
+ # bids = options.bids
+@@ -158,7 +158,7 @@ class GroopMOptionsParser():
+ pfx="REFINED"
+ else:
+ pfx=""
+- print "Refine bins"
++ print("Refine bins")
+
+ RE.refineBins(timer,
+ auto=auto,
+@@ -167,9 +167,9 @@ class GroopMOptionsParser():
+
+ elif(options.subparser_name == 'recruit'):
+ # make bin cores
+- print "*******************************************************************************"
+- print " [[GroopM %s]] Running in bin expansion mode..." % self.GMVersion
+- print "*******************************************************************************"
++ print("*******************************************************************************")
++ print(" [[GroopM %s]] Running in bin expansion mode..." % self.GMVersion)
++ print("*******************************************************************************")
+ RE = refine.RefineEngine(timer,
+ dbFileName=options.dbname,
+ getUnbinned=True,
+@@ -183,9 +183,9 @@ class GroopMOptionsParser():
+
+ elif(options.subparser_name == 'extract'):
+ # Extract data
+- print "*******************************************************************************"
+- print " [[GroopM %s]] Running in '%s' extraction mode..." % (self.GMVersion, options.mode)
+- print "*******************************************************************************"
++ print("*******************************************************************************")
++ print(" [[GroopM %s]] Running in '%s' extraction mode..." % (self.GMVersion, options.mode))
++ print("*******************************************************************************")
+ bids = []
+ if options.bids is not None:
+ bids = options.bids
+@@ -220,35 +220,35 @@ class GroopMOptionsParser():
+ raise ExtractModeNotAppropriateException("mode: "+ options.mode + " is unknown")
+ elif(options.subparser_name == 'merge'):
+ # make bin cores
+- print "*******************************************************************************"
+- print " [[GroopM %s]] Running in bin merging mode..." % self.GMVersion
+- print "*******************************************************************************"
++ print("*******************************************************************************")
++ print(" [[GroopM %s]] Running in bin merging mode..." % self.GMVersion)
++ print("*******************************************************************************")
+ BM = binManager.BinManager(dbFileName=options.dbname)
+ BM.loadBins(timer, makeBins=True, silent=False)
+ BM.merge(options.bids, options.force, saveBins=True)
+
+ elif(options.subparser_name == 'split'):
+ # make bin cores
+- print "*******************************************************************************"
+- print " [[GroopM %s]] Running in bin splitting mode..." % self.GMVersion
+- print "*******************************************************************************"
++ print("*******************************************************************************")
++ print(" [[GroopM %s]] Running in bin splitting mode..." % self.GMVersion)
++ print("*******************************************************************************")
+ BM = binManager.BinManager(dbFileName=options.dbname)
+ BM.loadBins(timer, makeBins=True, silent=False)
+ BM.split(options.bid, options.parts, mode=options.mode, saveBins=True, auto=options.force)
+
+ elif(options.subparser_name == 'delete'):
+ # make bin cores
+- print "*******************************************************************************"
+- print " [[GroopM %s]] Running in bin deleting mode..." % self.GMVersion
+- print "*******************************************************************************"
++ print("*******************************************************************************")
++ print(" [[GroopM %s]] Running in bin deleting mode..." % self.GMVersion)
++ print("*******************************************************************************")
+ BM = binManager.BinManager(dbFileName=options.dbname)
+ BM.loadBins(timer, makeBins=True, silent=True)#, bids=options.bids)
+ BM.deleteBins(options.bids, force=options.force, saveBins=True, freeBinnedRowIndices=True)
+
+ elif(options.subparser_name == 'plot'):
+- print "*******************************************************************************"
+- print " [[GroopM %s]] Running in bin plotting mode..." % self.GMVersion
+- print "*******************************************************************************"
++ print("*******************************************************************************")
++ print(" [[GroopM %s]] Running in bin plotting mode..." % self.GMVersion)
++ print("*******************************************************************************")
+ BM = binManager.BinManager(dbFileName=options.dbname)
+
+ if options.bids is None:
+@@ -266,9 +266,9 @@ class GroopMOptionsParser():
+
+ elif(options.subparser_name == 'explore'):
+ # make bin cores
+- print "*******************************************************************************"
+- print " [[GroopM %s]] Running in bin '%s' explorer mode..." % (self.GMVersion, options.mode)
+- print "*******************************************************************************"
++ print("*******************************************************************************")
++ print(" [[GroopM %s]] Running in bin '%s' explorer mode..." % (self.GMVersion, options.mode))
++ print("*******************************************************************************")
+ transform=True^options.no_transform
+ bids = []
+ if options.bids is not None:
+@@ -297,13 +297,13 @@ class GroopMOptionsParser():
+ elif (options.mode == 'sidebyside'):
+ BE.plotSideBySide(timer, coreCut=options.cutoff)
+ else:
+- print "**Error: unknown mode:",options.mode
++ print("**Error: unknown mode:",options.mode)
+
+ elif(options.subparser_name == 'flyover'):
+ # make bin cores
+- print "*******************************************************************************"
+- print " [[GroopM %s]] Making a flyover..." % self.GMVersion
+- print "*******************************************************************************"
++ print("*******************************************************************************")
++ print(" [[GroopM %s]] Making a flyover..." % self.GMVersion)
++ print("*******************************************************************************")
+ bids = []
+ if options.bids is not None:
+ bids = options.bids
+@@ -323,9 +323,9 @@ class GroopMOptionsParser():
+
+ elif(options.subparser_name == 'highlight'):
+ # make bin cores
+- print "*******************************************************************************"
+- print " [[GroopM %s]] Running in highlighter mode..." % self.GMVersion
+- print "*******************************************************************************"
++ print("*******************************************************************************")
++ print(" [[GroopM %s]] Running in highlighter mode..." % self.GMVersion)
++ print("*******************************************************************************")
+ bids = []
+ if options.bids is not None:
+ bids = options.bids
+@@ -355,9 +355,9 @@ class GroopMOptionsParser():
+ BM.printBins(options.format, fileName=options.outfile)
+
+ elif(options.subparser_name == 'dump'):
+- print "*******************************************************************************"
+- print " [[GroopM %s]] Running in data dumping mode..." % self.GMVersion
+- print "*******************************************************************************"
++ print("*******************************************************************************")
++ print(" [[GroopM %s]] Running in data dumping mode..." % self.GMVersion)
++ print("*******************************************************************************")
+
+ # prep fields. Do this first cause users are mot likely to
+ # mess this part up!
+@@ -365,8 +365,8 @@ class GroopMOptionsParser():
+ fields = options.fields.split(',')
+ for field in fields:
+ if field not in allowable_fields:
+- print "ERROR: field '%s' not recognised. Allowable fields are:" % field
+- print '\t',",".join(allowable_fields)
++ print("ERROR: field '%s' not recognised. Allowable fields are:" % field)
++ print('\t',",".join(allowable_fields))
+ return
+ if options.separator == '\\t':
+ separator = '\t'
+--- groopm/groopmUtils.py.orig 2014-11-26 01:01:33 UTC
++++ groopm/groopmUtils.py
+@@ -62,8 +62,8 @@ np.seterr(all='raise')
+ from scipy.spatial.distance import cdist, squareform
+
+ # GroopM imports
+-import binManager
+-import mstore
++from . import binManager
++from . import mstore
+
+ # other local imports
+ from bamm.bamExtractor import BamExtractor as BMBE
+@@ -126,16 +126,16 @@ class GMExtractor:
+ import gzip
+ GM_open = gzip.open
+ except:
+- print "Error when guessing contig file mimetype"
++ print("Error when guessing contig file mimetype")
+ raise
+ with GM_open(file_name, "r") as f:
+ contigs = CP.getWantedSeqs(f, self.PM.contigNames, storage=contigs)
+ except:
+- print "Could not parse contig file:",fasta[0],sys.exc_info()[0]
++ print("Could not parse contig file:",fasta[0],sys.exc_info()[0])
+ raise
+
+ # now print out the sequences
+- print "Writing files"
++ print("Writing files")
+ for bid in self.BM.getBids():
+ if self.BM.PM.isLikelyChimeric[bid]:
+ file_name = os.path.join(self.outDir, "%s_bin_%d.chimeric.fna" % (self.prefix, bid))
+@@ -148,9 +148,9 @@ class GMExtractor:
+ if(cid in contigs):
+ f.write(">%s\n%s\n" % (cid, contigs[cid]))
+ else:
+- print "These are not the contigs you're looking for. ( %s )" % (cid)
++ print("These are not the contigs you're looking for. ( %s )" % (cid))
+ except:
+- print "Could not open file for writing:",file_name,sys.exc_info()[0]
++ print("Could not open file for writing:",file_name,sys.exc_info()[0])
+ raise
+
+ def extractReads(self,
+@@ -177,7 +177,7 @@ class GMExtractor:
+ self.BM.loadBins(timer, makeBins=True,silent=False,bids=self.bids)
+ self.PM = self.BM.PM
+
+- print "Extracting reads"
++ print("Extracting reads")
+
+ # work out a set of targets to pass to the parser
+ targets = []
+@@ -268,16 +268,16 @@ class BinExplorer:
+ transform = self.transform,
+ cutOff=coreCut)
+ if len(self.BM.bins) == 0:
+- print "Sorry, no bins to plot"
++ print("Sorry, no bins to plot")
+ else:
+- print "Plotting image"
++ print("Plotting image")
+ if self.bids == []:
+ self.bids = self.BM.getBids()
+
+ if testing:
+ # ignore labelling files provided
+ self.binLabelsFile = "none"
+- raw_input( "****************************************************************\n"
++ input( "****************************************************************\n"
+ " IMAGE MAKING INSTRUCTIONS - PLEASE READ CAREFULLY\n"
+ "****************************************************************\n"
+ " You are using GroopM in highlight mode. Congratulations!\n"
+@@ -290,7 +290,7 @@ class BinExplorer:
+ " parameters to what you saw here, set bin labels, contig colours...\n\n"
+ " Good Luck!\n\n"
+ " Press return to continue...")
+- print "****************************************************************"
++ print("****************************************************************")
+
+ # bids as labels and randomise colours
+ self.LP = LabelParser(self.BM.getBids())
+@@ -457,9 +457,9 @@ class BinExplorer:
+ cutOff=coreCut,
+ getUnbinned=True,)
+ if len(self.BM.bins) == 0:
+- print "Sorry, no bins to plot"
++ print("Sorry, no bins to plot")
+ else:
+- print "Plotting flyover"
++ print("Plotting flyover")
+
+ import itertools
+ all_bids = self.BM.getBids()
+@@ -475,7 +475,7 @@ class BinExplorer:
+ elev_increment = total_elev_shift / total_frames
+ self.BM.setColorMap(self.cmString)
+
+- print "Need",total_frames,"frames:"
++ print("Need",total_frames,"frames:")
+
+ """
+ Handle taking out bins as "fade packets", assign indices to a list
+@@ -510,17 +510,17 @@ class BinExplorer:
+ # make the fade schedule for the remaining bins
+ remaining_frames = float(total_frames - fade_schedules[0])
+ num_fade_gs = float(len(fade_groups) - 1)
+- fade_schedules += [len(i) for i in self.splitCeil(range(int(remaining_frames)), int(num_fade_gs))]
++ fade_schedules += [len(i) for i in self.splitCeil(list(range(int(remaining_frames))), int(num_fade_gs))]
+
+ if False:
+- print len(self.BM.getBids()), num_fade_gs
+- print fade_groups
+- print fade_schedules
++ print(len(self.BM.getBids()), num_fade_gs)
++ print(fade_groups)
++ print(fade_schedules)
+
+ # plot all contigs first and then fade out
+ fig = plt.figure()
+ while len(fade_groups) >= 1:
+- print "Rendering frame: %d of: %d" % (int(current_frame),int(total_frames))
++ print("Rendering frame: %d of: %d" % (int(current_frame),int(total_frames)))
+ # get the next fade group and fade schedule
+ faders = fade_groups.pop(0)
+ fade_schedule = fade_schedules.pop(0)
+@@ -555,16 +555,16 @@ class BinExplorer:
+ bids=self.bids,
+ transform=self.transform)
+ if len(self.BM.bins) == 0:
+- print "Sorry, no bins to plot"
++ print("Sorry, no bins to plot")
+ else:
+- print "Plotting bin profiles"
++ print("Plotting bin profiles")
+ self.BM.setColorMap(self.cmString)
+ self.BM.plotProfileDistributions()
+
+ def plotContigs(self, timer, coreCut, all=False):
+ """plot contigs"""
+ if all:
+- print "Plotting all contigs"
++ print("Plotting all contigs")
+ self.PM.plotAll(timer, coreCut, transform=self.transform, ignoreContigLengths=self.ignoreContigLengths)
+ else:
+ self.BM.loadBins(timer,
+@@ -574,9 +574,9 @@ class BinExplorer:
+ transform=self.transform,
+ cutOff=coreCut)
+ if len(self.BM.bins) == 0:
+- print "Sorry, no bins to plot"
++ print("Sorry, no bins to plot")
+ else:
+- print "Plotting binned contigs"
++ print("Plotting binned contigs")
+ self.BM.setColorMap(self.cmString)
+ if self.bids == []:
+ self.bids = self.BM.getBids()
+@@ -592,9 +592,9 @@ class BinExplorer:
+ cutOff=coreCut,
+ transform=self.transform)
+ if len(self.BM.bins) == 0:
+- print "Sorry, no bins to plot"
++ print("Sorry, no bins to plot")
+ else:
+- print "Plotting bin assignments"
++ print("Plotting bin assignments")
+ if self.bids == []:
+ self.bids = self.BM.getBids()
+
+@@ -696,9 +696,9 @@ class BinExplorer:
+ transform=self.transform,
+ cutOff=coreCut)
+ if len(self.BM.bins) == 0:
+- print "Sorry, no bins to plot"
++ print("Sorry, no bins to plot")
+ else:
+- print "Plotting bin points"
++ print("Plotting bin points")
+ self.BM.setColorMap(self.cmString)
+ self.BM.plotBinPoints()
+
+@@ -726,9 +726,9 @@ class BinExplorer:
+ self.BM.setColorMap(self.cmString)
+
+ if len(self.BM.bins) == 0:
+- print "Sorry, no bins to plot"
++ print("Sorry, no bins to plot")
+ else:
+- print "Plotting side by side graphs"
++ print("Plotting side by side graphs")
+ (bin_centroid_points, bin_centroid_colors, bin_centroid_gc, bin_ids) = self.BM.findCoreCentres()
+ self.plotCoresVsContigs(bin_centroid_points, bin_centroid_colors)
+
+@@ -743,15 +743,15 @@ class BinExplorer:
+ bids=self.bids,
+ transform=self.transform)
+ if len(self.BM.bins) == 0:
+- print "Sorry, no bins to plot"
++ print("Sorry, no bins to plot")
+ else:
+- print "Plotting bin IDs"
++ print("Plotting bin IDs")
+ self.BM.setColorMap(self.cmString)
+ self.BM.plotBinIds()
+
+ def plotUnbinned(self, timer, coreCut):
+ """Plot all contigs over a certain length which are unbinned"""
+- print "Plotting unbinned contigs"
++ print("Plotting unbinned contigs")
+ self.PM.plotUnbinned(timer, coreCut, transform=self.transform, ignoreContigLengths=self.ignoreContigLengths)
+
+ def plotSideBySide(self, timer, coreCut):
+@@ -763,7 +763,7 @@ class BinExplorer:
+ transform=self.transform,
+ cutOff=coreCut)
+ if len(self.BM.bins) == 0:
+- print "Sorry, no bins to plot"
++ print("Sorry, no bins to plot")
+ else:
+ self.BM.setColorMap(self.cmString)
+ self.BM.plotBins(sideBySide=True,
+@@ -779,9 +779,9 @@ class BinExplorer:
+ transform=self.transform,
+ cutOff=coreCut)
+ if len(self.BM.bins) == 0:
+- print "Sorry, no bins to plot"
++ print("Sorry, no bins to plot")
+ else:
+- print "Plotting all bins together"
++ print("Plotting all bins together")
+ self.BM.setColorMap(self.cmString)
+ if self.bids == []:
+ p_bids = self.BM.getBids()
+@@ -832,7 +832,7 @@ class BinExplorer:
+ plt.show()
+ plt.close(fig)
+ except:
+- print "Error showing image", sys.exc_info()[0]
++ print("Error showing image", sys.exc_info()[0])
+ raise
+ del fig
+ else:
+@@ -859,7 +859,7 @@ class BinExplorer:
+ plt.savefig(f_name1,dpi=dpi,format=format)
+ plt.close(fig)
+ except:
+- print "Error saving image",f_name1, sys.exc_info()[0]
++ print("Error saving image",f_name1, sys.exc_info()[0])
+ raise
+ del fig
+
+@@ -893,7 +893,7 @@ class BinExplorer:
+ plt.savefig(f_name2,dpi=dpi,format=format)
+ plt.close(fig)
+ except:
+- print "Error saving image",f_name1, sys.exc_info()[0]
++ print("Error saving image",f_name1, sys.exc_info()[0])
+ raise
+ del fig
+
+@@ -1137,9 +1137,9 @@ class LabelParser:
+ try:
+ self.contig2Cols[name_2_row_index[cid]] = self.rgb(fields[1])
+ except KeyError:
+- print "ERROR: contig name %s not recognised" % cid
++ print("ERROR: contig name %s not recognised" % cid)
+ except:
+- print "ERROR: parsing labels file: %s" % labelFileName
++ print("ERROR: parsing labels file: %s" % labelFileName)
+ raise
+
+ # now we parse the rest of the contig names and colour the null colour
+@@ -1178,7 +1178,7 @@ class LabelParser:
+ except IndexError: pass
+ self.loaded[bid] = True
+ except:
+- print "ERROR parsing labels file: %s" % labelFileName
++ print("ERROR parsing labels file: %s" % labelFileName)
+ raise
+
+ def setDefaultBinLabels(self, bids):
+@@ -1192,7 +1192,7 @@ class LabelParser:
+ S = 1.0
+ V = 1.0
+ if setLoaded:
+- for bid in self.bin2Str.keys():
++ for bid in list(self.bin2Str.keys()):
+ self.loaded[bid] = True
+ num_bins = len(self.bin2Str)
+ offset = 0.5
+@@ -1201,7 +1201,7 @@ class LabelParser:
+ cols = [htr(H, S, V) for H in Hs]
+ np.random.shuffle(cols)
+ i = 0
+- for bid in self.bin2Str.keys():
++ for bid in list(self.bin2Str.keys()):
+ if self.loaded[bid]:
+ # assign the color we picked
+ self.bin2Cols[bid] = cols[i]
+--- groopm/mstore.py.orig 2015-03-06 04:42:41 UTC
++++ groopm/mstore.py
+@@ -58,7 +58,7 @@ import numpy as np
+ from scipy.spatial.distance import cdist, squareform
+
+ # GroopM imports
+-from PCA import PCA, Center
++from .PCA import PCA, Center
+
+ # BamM imports
+ try:
+@@ -66,7 +66,7 @@ try:
+ from bamm.cWrapper import *
+ from bamm.bamFile import BM_coverageType as BMCT
+ except ImportError:
+- print """ERROR: There was an error importing BamM. This probably means that
++ print("""ERROR: There was an error importing BamM. This probably means that
+ BamM is not installed properly or not in your PYTHONPATH. Installation
+ instructions for BamM are located at:
+
+@@ -79,7 +79,7 @@ you still encounter this error. Please lodge a bug rep
+
+ Exiting...
+ --------------------------------------------------------------------------------
+-"""
++""")
+ import sys
+ sys.exit(-1)
+
+@@ -217,12 +217,12 @@ class GMDataManager:
+ if(not force):
+ user_option = self.promptOnOverwrite(dbFileName)
+ if(user_option != "Y"):
+- print "Operation cancelled"
++ print("Operation cancelled")
+ return False
+ else:
+- print "Overwriting database",dbFileName
++ print("Overwriting database",dbFileName)
+ except IOError as e:
+- print "Creating new database", dbFileName
++ print("Creating new database", dbFileName)
+
+ # create the db
+ try:
+@@ -251,19 +251,19 @@ class GMDataManager:
+ import gzip
+ GM_open = gzip.open
+ except:
+- print "Error when guessing contig file mimetype"
++ print("Error when guessing contig file mimetype")
+ raise
+ try:
+ with GM_open(contigsFile, "r") as f:
+ try:
+ (con_names, con_gcs, con_lengths, con_ksigs) = conParser.parse(f, cutoff, kse)
+ num_cons = len(con_names)
+- cid_2_indices = dict(zip(con_names, range(num_cons)))
++ cid_2_indices = dict(list(zip(con_names, list(range(num_cons)))))
+ except:
+- print "Error parsing contigs"
++ print("Error parsing contigs")
+ raise
+ except:
+- print "Could not parse contig file:",contigsFile,exc_info()[0]
++ print("Could not parse contig file:",contigsFile,exc_info()[0])
+ raise
+
+ #------------------------
+@@ -280,15 +280,15 @@ class GMDataManager:
+ if len(bad_indices) > 0:
+ # report the bad contigs to the user
+ # and strip them before writing to the DB
+- print "****************************************************************"
+- print " IMPORTANT! - there are %d contigs with 0 coverage" % len(bad_indices)
+- print " across all stoits. They will be ignored:"
+- print "****************************************************************"
+- for i in xrange(0, min(5, len(bad_indices))):
+- print con_names[bad_indices[i]]
++ print("****************************************************************")
++ print(" IMPORTANT! - there are %d contigs with 0 coverage" % len(bad_indices))
++ print(" across all stoits. They will be ignored:")
++ print("****************************************************************")
++ for i in range(0, min(5, len(bad_indices))):
++ print(con_names[bad_indices[i]])
+ if len(bad_indices) > 5:
+- print '(+ %d additional contigs)' % (len(bad_indices)-5)
+- print "****************************************************************"
++ print('(+ %d additional contigs)' % (len(bad_indices)-5))
++ print("****************************************************************")
+
+ con_names = con_names[good_indices]
+ con_lengths = con_lengths[good_indices]
+@@ -314,14 +314,14 @@ class GMDataManager:
+ expectedrows=num_cons
+ )
+ except:
+- print "Error creating KMERSIG table:", exc_info()[0]
++ print("Error creating KMERSIG table:", exc_info()[0])
+ raise
+
+ # compute the PCA of the ksigs and store these too
+ pc_ksigs, sumvariance = conParser.PCAKSigs(con_ksigs)
+
+ db_desc = []
+- for i in xrange(0, len(pc_ksigs[0])):
++ for i in range(0, len(pc_ksigs[0])):
+ db_desc.append(('pc' + str(i+1), float))
+
+ try:
+@@ -332,7 +332,7 @@ class GMDataManager:
+ expectedrows=num_cons
+ )
+ except:
+- print "Error creating KMERVALS table:", exc_info()[0]
++ print("Error creating KMERVALS table:", exc_info()[0])
+ raise
+
+ #------------------------
+@@ -378,7 +378,7 @@ class GMDataManager:
+ title="Bam based coverage",
+ expectedrows=num_cons)
+ except:
+- print "Error creating coverage table:", exc_info()[0]
++ print("Error creating coverage table:", exc_info()[0])
+ raise
+
+ # transformed coverages
+@@ -392,7 +392,7 @@ class GMDataManager:
+ title="Transformed coverage",
+ expectedrows=num_cons)
+ except:
+- print "Error creating transformed coverage table:", exc_info()[0]
++ print("Error creating transformed coverage table:", exc_info()[0])
+ raise
+
+ # transformed coverage corners
+@@ -406,7 +406,7 @@ class GMDataManager:
+ title="Transformed coverage corners",
+ expectedrows=len(stoitColNames))
+ except:
+- print "Error creating transformed coverage corner table:", exc_info()[0]
++ print("Error creating transformed coverage corner table:", exc_info()[0])
+ raise
+
+ # normalised coverages
+@@ -418,16 +418,16 @@ class GMDataManager:
+ title="Normalised coverage",
+ expectedrows=num_cons)
+ except:
+- print "Error creating normalised coverage table:", exc_info()[0]
++ print("Error creating normalised coverage table:", exc_info()[0])
+ raise
+
+ #------------------------
+ # Add a table for the contigs
+ #------------------------
+ self.setBinAssignments((h5file, meta_group),
+- image=zip(con_names,
++ image=list(zip(con_names,
+ [0]*num_cons,
+- con_lengths, con_gcs)
++ con_lengths, con_gcs))
+ )
+
+ #------------------------
+@@ -435,7 +435,7 @@ class GMDataManager:
+ #------------------------
+ self.initBinStats((h5file, meta_group))
+
+- print " %s" % timer.getTimeStamp()
++ print(" %s" % timer.getTimeStamp())
+
+ #------------------------
+ # contig links
+@@ -454,9 +454,9 @@ class GMDataManager:
+ title="ContigLinks",
+ expectedrows=len(rowwise_links))
+ except:
+- print "Error creating links table:", exc_info()[0]
++ print("Error creating links table:", exc_info()[0])
+ raise
+- print " %s" % timer.getTimeStamp()
++ print(" %s" % timer.getTimeStamp())
+
+ #------------------------
+ # Add metadata
+@@ -475,12 +475,12 @@ class GMDataManager:
+
+ # kmer signature variance table
+ pc_var = [sumvariance[0]]
+- for i in xrange(1, len(sumvariance)):
++ for i in range(1, len(sumvariance)):
+ pc_var.append(sumvariance[i]-sumvariance[i-1])
+ pc_var = tuple(pc_var)
+
+ db_desc = []
+- for i in xrange(0, len(pc_var)):
++ for i in range(0, len(pc_var)):
+ db_desc.append(('pc' + str(i+1) + '_var', float))
+
+ try:
+@@ -491,20 +491,20 @@ class GMDataManager:
+ expectedrows=1
+ )
+ except:
+- print "Error creating tmp_kpca_variance table:", exc_info()[0]
++ print("Error creating tmp_kpca_variance table:", exc_info()[0])
+ raise
+
+ except:
+- print "Error creating database:", dbFileName, exc_info()[0]
++ print("Error creating database:", dbFileName, exc_info()[0])
+ raise
+
+- print "****************************************************************"
+- print "Data loaded successfully!"
+- print " ->",num_cons,"contigs"
+- print " ->",len(stoitColNames),"BAM files"
+- print "Written to: '"+dbFileName+"'"
+- print "****************************************************************"
+- print " %s" % timer.getTimeStamp()
++ print("****************************************************************")
++ print("Data loaded successfully!")
++ print(" ->",num_cons,"contigs")
++ print(" ->",len(stoitColNames),"BAM files")
++ print("Written to: '"+dbFileName+"'")
++ print("****************************************************************")
++ print(" %s" % timer.getTimeStamp())
+
+ # all good!
+ return True
+@@ -516,17 +516,17 @@ class GMDataManager:
+ vrs = ",".join([str.lower(str(x)) for x in valid_responses])
+ while(input_not_ok):
+ if(minimal):
+- option = raw_input(" Overwrite? ("+vrs+") : ")
++ option = input(" Overwrite? ("+vrs+") : ")
+ else:
+
+- option = raw_input(" ****WARNING**** Database: '"+dbFileName+"' exists.\n" \
++ option = input(" ****WARNING**** Database: '"+dbFileName+"' exists.\n" \
+ " If you continue you *WILL* delete any previous analyses!\n" \
+ " Overwrite? ("+vrs+") : ")
+ if(option.upper() in valid_responses):
+- print "****************************************************************"
++ print("****************************************************************")
+ return option.upper()
+ else:
+- print "Error, unrecognised choice '"+option.upper()+"'"
++ print("Error, unrecognised choice '"+option.upper()+"'")
+ minimal = True
+
+ #------------------------------------------------------------------------------
+@@ -538,7 +538,7 @@ class GMDataManager:
+ this_DB_version = self.getGMDBFormat(dbFileName)
+ if __current_GMDB_version__ == this_DB_version:
+ if not silent:
+- print " GroopM DB version (%s) up to date" % this_DB_version
++ print(" GroopM DB version (%s) up to date" % this_DB_version)
+ return
+
+ # now, if we get here then we need to do some work
+@@ -558,14 +558,14 @@ class GMDataManager:
+
+ def upgradeDB_0_to_1(self, dbFileName):
+ """Upgrade a GM db from version 0 to version 1"""
+- print "*******************************************************************************\n"
+- print " *** Upgrading GM DB from version 0 to version 1 ***"
+- print ""
+- print " please be patient..."
+- print ""
++ print("*******************************************************************************\n")
++ print(" *** Upgrading GM DB from version 0 to version 1 ***")
++ print("")
++ print(" please be patient...")
++ print("")
+ # the change in this version is that we'll be saving the first
+ # two kmerSig PCA's in a separate table
+- print " Calculating and storing the kmerSig PCAs"
++ print(" Calculating and storing the kmerSig PCAs")
+
+ # compute the PCA of the ksigs
+ ksigs = self.getKmerSigs(dbFileName)
+@@ -585,26 +585,26 @@ class GMDataManager:
+ expectedrows=num_cons
+ )
+ except:
+- print "Error creating KMERVALS table:", exc_info()[0]
++ print("Error creating KMERVALS table:", exc_info()[0])
+ raise
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ # update the formatVersion field and we're done
+ self.setGMDBFormat(dbFileName, 1)
+- print "*******************************************************************************"
++ print("*******************************************************************************")
+
+ def upgradeDB_1_to_2(self, dbFileName):
+ """Upgrade a GM db from version 1 to version 2"""
+- print "*******************************************************************************\n"
+- print " *** Upgrading GM DB from version 1 to version 2 ***"
+- print ""
+- print " please be patient..."
+- print ""
++ print("*******************************************************************************\n")
++ print(" *** Upgrading GM DB from version 1 to version 2 ***")
++ print("")
++ print(" please be patient...")
++ print("")
+ # the change in this version is that we'll be saving a variable number of kmerSig PCA's
+ # and GC information for each contig
+- print " Calculating and storing the kmer signature PCAs"
++ print(" Calculating and storing the kmer signature PCAs")
+
+ # grab any data needed from database before opening if for modification
+ bin_ids = self.getBins(dbFileName)
+@@ -617,7 +617,7 @@ class GMDataManager:
+ num_cons = len(pc_ksigs)
+
+ db_desc = []
+- for i in xrange(0, len(pc_ksigs[0])):
++ for i in range(0, len(pc_ksigs[0])):
+ db_desc.append(('pc' + str(i+1), float))
+
+ try:
+@@ -639,11 +639,11 @@ class GMDataManager:
+ h5file.renameNode(pg, 'kpca', 'tmp_kpca', overwrite=True)
+
+ except:
+- print "Error creating kpca table:", exc_info()[0]
++ print("Error creating kpca table:", exc_info()[0])
+ raise
+
+ # Add GC
+- contigFile = raw_input('\nPlease specify fasta file containing the bam reference sequences: ')
++ contigFile = input('\nPlease specify fasta file containing the bam reference sequences: ')
+ with open(contigFile, "r") as f:
+ try:
+ contigInfo = {}
+@@ -657,7 +657,7 @@ class GMDataManager:
+ con_gcs = np.array([contigInfo[cid][1] for cid in con_names])
+ con_lengths = np.array([contigInfo[cid][0] for cid in con_names])
+ except:
+- print "Error parsing contigs"
++ print("Error parsing contigs")
+ raise
+
+ # remove any contigs not in the current DB (these were removed due to having zero coverage)
+@@ -670,27 +670,27 @@ class GMDataManager:
+
+ mg = h5file.getNode('/', name='meta')
+ self.setBinAssignments((h5file, mg),
+- image=zip(con_names,
++ image=list(zip(con_names,
+ bin_ids,
+- con_lengths, con_gcs)
++ con_lengths, con_gcs))
+ )
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ # update the formatVersion field and we're done
+ self.setGMDBFormat(dbFileName, 2)
+- print "*******************************************************************************"
++ print("*******************************************************************************")
+
+ def upgradeDB_2_to_3(self, dbFileName):
+ """Upgrade a GM db from version 2 to version 3"""
+- print "*******************************************************************************\n"
+- print " *** Upgrading GM DB from version 2 to version 3 ***"
+- print ""
+- print " please be patient..."
+- print ""
++ print("*******************************************************************************\n")
++ print(" *** Upgrading GM DB from version 2 to version 3 ***")
++ print("")
++ print(" please be patient...")
++ print("")
+ # the change in this version is that we'll be saving the variance for each kmerSig PCA
+- print " Calculating and storing variance of kmer signature PCAs"
++ print(" Calculating and storing variance of kmer signature PCAs")
+
+ # compute the PCA of the ksigs
+ conParser = ContigParser()
+@@ -699,12 +699,12 @@ class GMDataManager:
+
+ # calcualte variance of each PC
+ pc_var = [sumvariance[0]]
+- for i in xrange(1, len(sumvariance)):
++ for i in range(1, len(sumvariance)):
+ pc_var.append(sumvariance[i]-sumvariance[i-1])
+ pc_var = tuple(pc_var)
+
+ db_desc = []
+- for i in xrange(0, len(pc_var)):
++ for i in range(0, len(pc_var)):
+ db_desc.append(('pc' + str(i+1) + '_var', float))
+
+ try:
+@@ -726,26 +726,26 @@ class GMDataManager:
+ h5file.renameNode(meta, 'kpca_variance', 'tmp_kpca_variance', overwrite=True)
+
+ except:
+- print "Error creating kpca_variance table:", exc_info()[0]
++ print("Error creating kpca_variance table:", exc_info()[0])
+ raise
+ except:
+- print "Error opening DB:", dbFileName, exc_info()[0]
++ print("Error opening DB:", dbFileName, exc_info()[0])
+ raise
+
+ # update the formatVersion field and we're done
+ self.setGMDBFormat(dbFileName, 3)
+- print "*******************************************************************************"
++ print("*******************************************************************************")
+
+ def upgradeDB_3_to_4(self, dbFileName):
+ """Upgrade a GM db from version 3 to version 4"""
+- print "*******************************************************************************\n"
+- print " *** Upgrading GM DB from version 3 to version 4 ***"
+- print ""
+- print " please be patient..."
+- print ""
++ print("*******************************************************************************\n")
++ print(" *** Upgrading GM DB from version 3 to version 4 ***")
++ print("")
++ print(" please be patient...")
++ print("")
+ # the change in this version is that we'll be saving the variance for each kmerSig PCA
+- print " Adding chimeric flag for each bin."
+- print " !!! Groopm core must be run again for this flag to be properly set. !!!"
++ print(" Adding chimeric flag for each bin.")
++ print(" !!! Groopm core must be run again for this flag to be properly set. !!!")
+
+ # read existing data in 'bins' table
+ try:
+@@ -755,7 +755,7 @@ class GMDataManager:
+ for row in all_rows:
+ ret_dict[row[0]] = row[1]
+ except:
+- print "Error opening DB:", dbFileName, exc_info()[0]
++ print("Error opening DB:", dbFileName, exc_info()[0])
+ raise
+
+ # write new table with chimeric flag set to False by default
+@@ -785,28 +785,28 @@ class GMDataManager:
+ title="Bin information",
+ expectedrows=1)
+ except:
+- print "Error creating META table:", exc_info()[0]
++ print("Error creating META table:", exc_info()[0])
+ raise
+
+ h5file.renameNode(mg, 'bins', 'tmp_bins', overwrite=True)
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ # update the formatVersion field and we're done
+ self.setGMDBFormat(dbFileName, 4)
+- print "*******************************************************************************"
++ print("*******************************************************************************")
+
+ def upgradeDB_4_to_5(self, dbFileName):
+ """Upgrade a GM db from version 4 to version 5"""
+- print "*******************************************************************************\n"
+- print " *** Upgrading GM DB from version 4 to version 5 ***"
+- print ""
+- print " please be patient..."
+- print ""
++ print("*******************************************************************************\n")
++ print(" *** Upgrading GM DB from version 4 to version 5 ***")
++ print("")
++ print(" please be patient...")
++ print("")
+ # the change in this version is that we'll be saving the transformed coverage coords
+- print " Saving transformed coverage profiles"
+- print " You will not need to re-run parse or core due to this change"
++ print(" Saving transformed coverage profiles")
++ print(" You will not need to re-run parse or core due to this change")
+
+ # we need to get the raw coverage profiles and the kmerPCA1 data
+ indices = self.getConditionalIndices(dbFileName, silent=False, checkUpgrade=False)
+@@ -849,7 +849,7 @@ class GMDataManager:
+ title="Bam based coverage",
+ expectedrows=CT.numContigs)
+ except:
+- print "Error creating coverage table:", exc_info()[0]
++ print("Error creating coverage table:", exc_info()[0])
+ raise
+
+ h5file.renameNode(profile_group, 'coverage', 'tmp_coverages', overwrite=True)
+@@ -865,7 +865,7 @@ class GMDataManager:
+ title="Transformed coverage",
+ expectedrows=CT.numContigs)
+ except:
+- print "Error creating transformed coverage table:", exc_info()[0]
++ print("Error creating transformed coverage table:", exc_info()[0])
+ raise
+
+ # transformed coverage corners
+@@ -879,7 +879,7 @@ class GMDataManager:
+ title="Transformed coverage corners",
+ expectedrows=CT.numStoits)
+ except:
+- print "Error creating transformed coverage corner table:", exc_info()[0]
++ print("Error creating transformed coverage corner table:", exc_info()[0])
+ raise
+
+
+@@ -892,7 +892,7 @@ class GMDataManager:
+ title="Normalised coverage",
+ expectedrows=CT.numContigs)
+ except:
+- print "Error creating normalised coverage table:", exc_info()[0]
++ print("Error creating normalised coverage table:", exc_info()[0])
+ raise
+
+ # stoit col names may have been shuffled
+@@ -912,7 +912,7 @@ class GMDataManager:
+
+ # update the formatVersion field and we're done
+ self.setGMDBFormat(dbFileName, 5)
+- print "*******************************************************************************"
++ print("*******************************************************************************")
+
+
+ #------------------------------------------------------------------------------
+@@ -925,7 +925,7 @@ class GMDataManager:
+ with tables.openFile(dbFileName, mode='r') as h5file:
+ full_record = [list(x) for x in h5file.root.links.links.readWhere("contig1 >= 0")]
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ if indices == []:
+@@ -958,7 +958,7 @@ class GMDataManager:
+ with tables.openFile(dbFileName, mode='r') as h5file:
+ return np.array([x.nrow for x in h5file.root.meta.contigs.where(condition)])
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def getCoverageProfiles(self, dbFileName, condition='', indices=np.array([])):
+@@ -972,7 +972,7 @@ class GMDataManager:
+ condition = "cid != ''" # no condition breaks everything!
+ return np.array([list(h5file.root.profile.coverage[x.nrow]) for x in h5file.root.meta.contigs.where(condition)])
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def getTransformedCoverageProfiles(self, dbFileName, condition='', indices=np.array([])):
+@@ -986,7 +986,7 @@ class GMDataManager:
+ condition = "cid != ''" # no condition breaks everything!
+ return np.array([list(h5file.root.profile.transCoverage[x.nrow]) for x in h5file.root.meta.contigs.where(condition)])
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def getNormalisedCoverageProfiles(self, dbFileName, condition='', indices=np.array([])):
+@@ -1000,12 +1000,12 @@ class GMDataManager:
+ condition = "cid != ''" # no condition breaks everything!
+ return np.array([list(h5file.root.profile.normCoverage[x.nrow]) for x in h5file.root.meta.contigs.where(condition)])
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def nukeBins(self, dbFileName):
+ """Reset all bin information, completely"""
+- print " Clearing all old bin information from",dbFileName
++ print(" Clearing all old bin information from",dbFileName)
+ self.setBinStats(dbFileName, [])
+ self.setNumBins(dbFileName, 0)
+ self.setBinAssignments(dbFileName, updates={}, nuke=True)
+@@ -1061,13 +1061,13 @@ class GMDataManager:
+ title="Bin information",
+ expectedrows=1)
+ except:
+- print "Error creating META table:", exc_info()[0]
++ print("Error creating META table:", exc_info()[0])
+ raise
+
+ # rename the tmp table to overwrite
+ h5file.renameNode(mg, 'bins', 'tmp_bins', overwrite=True)
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def getBinStats(self, dbFileName):
+@@ -1085,7 +1085,7 @@ class GMDataManager:
+
+ return ret_dict
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+ return {}
+
+@@ -1100,7 +1100,7 @@ class GMDataManager:
+ condition = "cid != ''" # no condition breaks everything!
+ return np.array([list(x)[1] for x in h5file.root.meta.contigs.readWhere(condition)]).ravel()
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def setBinAssignments(self, storage, updates=None, image=None, nuke=False):
+@@ -1135,17 +1135,17 @@ class GMDataManager:
+ bins = self.getBins(dbFileName)
+
+ # now apply the updates
+- for tr in updates.keys():
++ for tr in list(updates.keys()):
+ bins[tr] = updates[tr]
+
+ # and build the image
+- image = np.array(zip(contig_names, bins, contig_lengths, contig_gcs),
++ image = np.array(list(zip(contig_names, bins, contig_lengths, contig_gcs)),
+ dtype=db_desc)
+
+ try:
+ h5file = tables.openFile(dbFileName, mode='a')
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+ meta_group = h5file.getNode('/', name='meta')
+ closeh5 = True
+@@ -1157,7 +1157,7 @@ class GMDataManager:
+ image = np.array(image,
+ dtype=db_desc)
+ else:
+- print "get with the program dude"
++ print("get with the program dude")
+ return
+
+ # now we write the data
+@@ -1174,7 +1174,7 @@ class GMDataManager:
+ title="Contig information",
+ expectedrows=num_cons)
+ except:
+- print "Error creating CONTIG table:", exc_info()[0]
++ print("Error creating CONTIG table:", exc_info()[0])
+ raise
+
+ # rename the tmp table to overwrite
+@@ -1193,7 +1193,7 @@ class GMDataManager:
+ condition = "cid != ''" # no condition breaks everything!
+ return np.array([list(x)[0] for x in h5file.root.meta.contigs.readWhere(condition)]).ravel()
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def getContigLengths(self, dbFileName, condition='', indices=np.array([])):
+@@ -1207,7 +1207,7 @@ class GMDataManager:
+ condition = "cid != ''" # no condition breaks everything!
+ return np.array([list(x)[2] for x in h5file.root.meta.contigs.readWhere(condition)]).ravel()
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def getContigGCs(self, dbFileName, condition='', indices=np.array([])):
+@@ -1221,7 +1221,7 @@ class GMDataManager:
+ condition = "cid != ''" # no condition breaks everything!
+ return np.array([list(x)[3] for x in h5file.root.meta.contigs.readWhere(condition)]).ravel()
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def getKmerSigs(self, dbFileName, condition='', indices=np.array([])):
+@@ -1235,7 +1235,7 @@ class GMDataManager:
+ condition = "cid != ''" # no condition breaks everything!
+ return np.array([list(h5file.root.profile.kms[x.nrow]) for x in h5file.root.meta.contigs.where(condition)])
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def getKmerPCAs(self, dbFileName, condition='', indices=np.array([])):
+@@ -1249,7 +1249,7 @@ class GMDataManager:
+ condition = "cid != ''" # no condition breaks everything!
+ return np.array([list(h5file.root.profile.kpca[x.nrow]) for x in h5file.root.meta.contigs.where(condition)])
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ #------------------------------------------------------------------------------
+@@ -1261,7 +1261,7 @@ class GMDataManager:
+ with tables.openFile(dbFileName, mode='r') as h5file:
+ return np.array(list(h5file.root.meta.kpca_variance[0]))
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def getTransformedCoverageCorners(self, dbFileName):
+@@ -1270,7 +1270,7 @@ class GMDataManager:
+ with tables.openFile(dbFileName, mode='r') as h5file:
+ return np.array([list(x) for x in h5file.root.meta.transCoverageCorners.read()])
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def setMeta(self, h5file, metaData, overwrite=False):
+@@ -1310,7 +1310,7 @@ class GMDataManager:
+ "Descriptive data",
+ expectedrows=1)
+ except:
+- print "Error creating META table:", exc_info()[0]
++ print("Error creating META table:", exc_info()[0])
+ raise
+
+ if overwrite:
+@@ -1324,7 +1324,7 @@ class GMDataManager:
+ # theres only one value
+ return h5file.root.meta.meta.read()[fieldName][0]
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def setGMDBFormat(self, dbFileName, version):
+@@ -1344,7 +1344,7 @@ class GMDataManager:
+ with tables.openFile(dbFileName, mode='a', rootUEP="/") as h5file:
+ self.setMeta(h5file, meta_data, overwrite=True)
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def getGMDBFormat(self, dbFileName):
+@@ -1397,7 +1397,7 @@ class GMDataManager:
+ with tables.openFile(dbFileName, mode='a', rootUEP="/") as h5file:
+ self.setMeta(h5file, meta_data, overwrite=True)
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def getNumBins(self, dbFileName):
+@@ -1417,7 +1417,7 @@ class GMDataManager:
+ with tables.openFile(dbFileName, mode='r') as h5file:
+ return h5file.root.meta.meta.read()['clustered']
+ except:
+- print "Error opening database:", dbFileName, exc_info()[0]
++ print("Error opening database:", dbFileName, exc_info()[0])
+ raise
+
+ def setClustered(self, dbFileName, state):
+@@ -1437,7 +1437,7 @@ class GMDataManager:
+ with tables.openFile(dbFileName, mode='a', rootUEP="/") as h5file:
+ self.setMeta(h5file, meta_data, overwrite=True)
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ def isComplete(self, dbFileName):
+@@ -1446,7 +1446,7 @@ class GMDataManager:
+ with tables.openFile(dbFileName, mode='r') as h5file:
+ return h5file.root.meta.meta.read()['complete']
+ except:
+- print "Error opening database:", dbFileName, exc_info()[0]
++ print("Error opening database:", dbFileName, exc_info()[0])
+ raise
+
+ def setComplete(self, dbFileName, state):
+@@ -1466,7 +1466,7 @@ class GMDataManager:
+ with tables.openFile(dbFileName, mode='a', rootUEP="/") as h5file:
+ self.setMeta(h5file, meta_data, overwrite=True)
+ except:
+- print "Error opening DB:",dbFileName, exc_info()[0]
++ print("Error opening DB:",dbFileName, exc_info()[0])
+ raise
+
+ #------------------------------------------------------------------------------
+@@ -1543,7 +1543,7 @@ class GMDataManager:
+ fh.write(separator+data_converters[j](data_arrays[j][i]))
+ fh.write('\n')
+ except:
+- print "Error opening output file %s for writing" % outFile
++ print("Error opening output file %s for writing" % outFile)
+ raise
+
+ ###############################################################################
+@@ -1574,7 +1574,7 @@ class ContigParser:
+
+ def parse(self, contigFile, cutoff, kse):
+ """Do the heavy lifting of parsing"""
+- print "Parsing contigs"
++ print("Parsing contigs")
+ contigInfo = {} # save everything here first so we can sort accordingly
+ for cid,seq in self.readFasta(contigFile):
+ if len(seq) >= cutoff:
+@@ -1619,7 +1619,7 @@ class ContigParser:
+
+ def getWantedSeqs(self, contigFile, wanted, storage={}):
+ """Do the heavy lifting of parsing"""
+- print "Parsing contigs"
++ print("Parsing contigs")
+ for cid,seq in self.readFasta(contigFile):
+ if(cid in wanted):
+ storage[cid] = seq
+@@ -1696,7 +1696,7 @@ class KmerSigEngine:
+ returns a tuple of floats which is the kmer sig
+ """
+ # tmp storage
+- sig = dict(zip(self.kmerCols, [0.0] * self.numMers))
++ sig = dict(list(zip(self.kmerCols, [0.0] * self.numMers)))
+ # the number fo kmers in this sequence
+ num_mers = len(seq)-self.kLen+1
+ for i in range(0,num_mers):
+@@ -1710,7 +1710,7 @@ class KmerSigEngine:
+ try:
+ return tuple([sig[x] / num_mers for x in self.kmerCols])
+ except ZeroDivisionError:
+- print "***WARNING*** Sequence '%s' is not playing well with the kmer signature engine " % seq
++ print("***WARNING*** Sequence '%s' is not playing well with the kmer signature engine " % seq)
+ return tuple([0.0] * self.numMers)
+
+ ###############################################################################
+@@ -1724,7 +1724,7 @@ class BamParser:
+
+ def parse(self, bamFiles, contigNames, cid2Indices, threads):
+ """Parse multiple bam files and store the results in the main DB"""
+- print "Parsing BAM files using %d threads" % threads
++ print("Parsing BAM files using %d threads" % threads)
+
+ BP = BMBP(BMCT(CT.P_MEAN_TRIMMED, 5, 5))
+ BP.parseBams(bamFiles,
+@@ -1736,8 +1736,8 @@ class BamParser:
+ # we need to make sure that the ordering of contig names is consistent
+ # first we get a dict that connects a contig name to the index in
+ # the coverages array
+- con_name_lookup = dict(zip(BP.BFI.contigNames,
+- range(len(BP.BFI.contigNames))))
++ con_name_lookup = dict(list(zip(BP.BFI.contigNames,
++ list(range(len(BP.BFI.contigNames))))))
+
+ # Next we build the cov_sigs array by appending the coverage
+ # profiles in the same order. We need to handle the case where
+@@ -1799,7 +1799,7 @@ class CoverageTransformer:
+ self.kmerNormPC1 = kmerNormPC1
+ self.covProfiles = coverageProfiles
+ self.stoitColNames = stoitColNames
+- self.indices = range(self.numContigs)
++ self.indices = list(range(self.numContigs))
+ self.scaleFactor = scaleFactor
+
+ # things we care about!
+@@ -1814,8 +1814,8 @@ class CoverageTransformer:
+ shrinkFn = lambda x:x
+
+ if(not silent):
+- print " Reticulating splines"
+- print " Dimensionality reduction"
++ print(" Reticulating splines")
++ print(" Dimensionality reduction")
+
+ unit_vectors = [(np.cos(i*2*np.pi/self.numStoits),np.sin(i*2*np.pi/self.numStoits)) for i in range(self.numStoits)]
+
+@@ -1954,13 +1954,13 @@ class CoverageTransformer:
+ # so we need to make sure that we get all the nodes in the ordering list
+ trier = 0 # start of a new disjoint ring
+ ordering = [trier]
+- while len(ordering) < len(lr_dict.keys()):
++ while len(ordering) < len(list(lr_dict.keys())):
+ try:
+ adding_index = lr_dict[trier][0] # ok IF this guy has a registered neighbour
+ if adding_index in ordering: # NOT ok if the neighbour is already in the list
+ raise IndexError()
+ ordering.append(adding_index)
+- while len(ordering) < len(lr_dict.keys()): # try consume the entire ring
++ while len(ordering) < len(list(lr_dict.keys())): # try consume the entire ring
+ # len(ordering) >= 2
+ last = ordering[-1]
+ if lr_dict[last][0] == ordering[-2]: # bi-directionality means this will always work
+@@ -1973,7 +1973,7 @@ class CoverageTransformer:
+ # stick (2 city system)
+ while(trier in ordering): # find the next index NOT in the ordering
+ trier += 1
+- if trier < len(lr_dict.keys()): # make sure it makes sense
++ if trier < len(list(lr_dict.keys())): # make sure it makes sense
+ ordering.append(trier)
+ break
+ else:
+@@ -1985,14 +1985,14 @@ class CoverageTransformer:
+ # single point
+ while(trier in ordering):
+ trier += 1
+- if trier < len(lr_dict.keys()): # make sure it makes sense
++ if trier < len(list(lr_dict.keys())): # make sure it makes sense
+ ordering.append(trier)
+
+ # sanity check
+ if len(ordering) != self.numStoits:
+- print "WATTUP, ordering is looking wrong!"
+- print ordering
+- print lr_dict
++ print("WATTUP, ordering is looking wrong!")
++ print(ordering)
++ print(lr_dict)
+
+ # reshuffle the contig order!
+ # yay for bubble sort!
+--- groopm/profileManager.py.orig 2015-03-06 07:00:49 UTC
++++ groopm/profileManager.py
+@@ -96,10 +96,10 @@ from scipy.spatial import KDTree as kdt
+ from scipy.stats import f_oneway, distributions
+
+ # GroopM imports
+-from PCA import PCA, Center
+-from mstore import GMDataManager
+-from bin import Bin, mungeCbar
+-import groopmExceptions as ge
++from .PCA import PCA, Center
++from .mstore import GMDataManager
++from .bin import Bin, mungeCbar
++from . import groopmExceptions as ge
+
+ np_seterr(all='raise')
+
+@@ -179,7 +179,7 @@ class ProfileManager:
+ if(silent):
+ verbose=False
+ if verbose:
+- print "Loading data from:", self.dbFileName
++ print("Loading data from:", self.dbFileName)
+
+ try:
+ self.numStoits = self.getNumStoits()
+@@ -188,19 +188,19 @@ class ProfileManager:
+ condition=condition,
+ silent=silent)
+ if(verbose):
+- print " Loaded indices with condition:", condition
++ print(" Loaded indices with condition:", condition)
+ self.numContigs = len(self.indices)
+
+ if self.numContigs == 0:
+- print " ERROR: No contigs loaded using condition:", condition
++ print(" ERROR: No contigs loaded using condition:", condition)
+ return
+
+ if(not silent):
+- print " Working with: %d contigs" % self.numContigs
++ print(" Working with: %d contigs" % self.numContigs)
+
+ if(loadCovProfiles):
+ if(verbose):
+- print " Loading coverage profiles"
++ print(" Loading coverage profiles")
+ self.covProfiles = self.dataManager.getCoverageProfiles(self.dbFileName, indices=self.indices)
+ self.normCoverages = self.dataManager.getNormalisedCoverageProfiles(self.dbFileName, indices=self.indices)
+
+@@ -209,14 +209,14 @@ class ProfileManager:
+
+ if loadRawKmers:
+ if(verbose):
+- print " Loading RAW kmer sigs"
++ print(" Loading RAW kmer sigs")
+ self.kmerSigs = self.dataManager.getKmerSigs(self.dbFileName, indices=self.indices)
+
+ if(loadKmerPCs):
+ self.kmerPCs = self.dataManager.getKmerPCAs(self.dbFileName, indices=self.indices)
+
+ if(verbose):
+- print " Loading PCA kmer sigs (" + str(len(self.kmerPCs[0])) + " dimensional space)"
++ print(" Loading PCA kmer sigs (" + str(len(self.kmerPCs[0])) + " dimensional space)")
+
+ self.kmerNormPC1 = np_copy(self.kmerPCs[:,0])
+ self.kmerNormPC1 -= np_min(self.kmerNormPC1)
+@@ -226,26 +226,26 @@ class ProfileManager:
+ self.kmerVarPC = self.dataManager.getKmerVarPC(self.dbFileName, indices=self.indices)
+
+ if(verbose):
+- print " Loading PCA kmer variance (total variance: %.2f" % np_sum(self.kmerVarPC) + ")"
++ print(" Loading PCA kmer variance (total variance: %.2f" % np_sum(self.kmerVarPC) + ")")
+
+ if(loadContigNames):
+ if(verbose):
+- print " Loading contig names"
++ print(" Loading contig names")
+ self.contigNames = self.dataManager.getContigNames(self.dbFileName, indices=self.indices)
+
+ if(loadContigLengths):
+ self.contigLengths = self.dataManager.getContigLengths(self.dbFileName, indices=self.indices)
+ if(verbose):
+- print " Loading contig lengths (Total: %d BP)" % ( sum(self.contigLengths) )
++ print(" Loading contig lengths (Total: %d BP)" % ( sum(self.contigLengths) ))
+
+ if(loadContigGCs):
+ self.contigGCs = self.dataManager.getContigGCs(self.dbFileName, indices=self.indices)
+ if(verbose):
+- print " Loading contig GC ratios (Average GC: %0.3f)" % ( np_mean(self.contigGCs) )
++ print(" Loading contig GC ratios (Average GC: %0.3f)" % ( np_mean(self.contigGCs) ))
+
+ if(makeColors):
+ if(verbose):
+- print " Creating color map"
++ print(" Creating color map")
+
+ # use HSV to RGB to generate colors
+ S = 1 # SAT and VAL remain fixed at 1. Reduce to make
+@@ -254,7 +254,7 @@ class ProfileManager:
+
+ if(loadBins):
+ if(verbose):
+- print " Loading bin assignments"
++ print(" Loading bin assignments")
+
+ self.binIds = self.dataManager.getBins(self.dbFileName, indices=self.indices)
+
+@@ -289,7 +289,7 @@ class ProfileManager:
+ self.stoitColNames = self.getStoitColNames()
+
+ except:
+- print "Error loading DB:", self.dbFileName, exc_info()[0]
++ print("Error loading DB:", self.dbFileName, exc_info()[0])
+ raise
+
+ def reduceIndices(self, deadRowIndices):
+@@ -419,7 +419,7 @@ class ProfileManager:
+ # we'd like to take it down to about 1500 or so RI's
+ # but we'd like to do this in a repeatable way
+ ideal_contig_num = 1500
+- sub_cons = range(len(self.indices))
++ sub_cons = list(range(len(self.indices)))
+ while len(sub_cons) > ideal_contig_num:
+ # select every second contig when sorted by norm cov
+ cov_sorted = np_argsort(self.normCoverages[sub_cons])
+@@ -497,7 +497,7 @@ class ProfileManager:
+ def transformCP(self, timer, silent=False, nolog=False):
+ """Do the main transformation on the coverage profile data"""
+ if(not silent):
+- print " Reticulating splines"
++ print(" Reticulating splines")
+ self.transformedCP = self.dataManager.getTransformedCoverageProfiles(self.dbFileName, indices=self.indices)
+ self.corners = self.dataManager.getTransformedCoverageCorners(self.dbFileName)
+ self.TCentre = np_mean(self.corners, axis=0)
+@@ -530,7 +530,7 @@ class ProfileManager:
+ def createColorMapHSV(self):
+ S = 1.0
+ V = 1.0
+- return LinearSegmentedColormap.from_list('GC', [htr((1.0 + np_sin(np_pi * (val/1000.0) - np_pi/2))/2., S, V) for val in xrange(0, 1000)], N=1000)
++ return LinearSegmentedColormap.from_list('GC', [htr((1.0 + np_sin(np_pi * (val/1000.0) - np_pi/2))/2., S, V) for val in range(0, 1000)], N=1000)
+
+ def setColorMap(self, colorMapStr):
+ if colorMapStr == 'HSV':
+@@ -617,7 +617,7 @@ class ProfileManager:
+ if self.numStoits == 3:
+ self.transformedCP = self.covProfiles
+ else:
+- print "Number of stoits != 3. You need to transform"
++ print("Number of stoits != 3. You need to transform")
+ self.transformCP(timer)
+
+ fig = plt.figure()
+@@ -633,7 +633,7 @@ class ProfileManager:
+ plt.show()
+ plt.close(fig)
+ except:
+- print "Error showing image", exc_info()[0]
++ print("Error showing image", exc_info()[0])
+ raise
+ del fig
+
+@@ -646,7 +646,7 @@ class ProfileManager:
+ if self.numStoits == 3:
+ self.transformedCP = self.covProfiles
+ else:
+- print "Number of stoits != 3. You need to transform"
++ print("Number of stoits != 3. You need to transform")
+ self.transformCP(timer)
+
+ fig = plt.figure()
+@@ -691,7 +691,7 @@ class ProfileManager:
+ plt.show()
+ plt.close(fig)
+ except:
+- print "Error showing image", exc_info()[0]
++ print("Error showing image", exc_info()[0])
+ raise
+ del fig
+
+@@ -801,7 +801,7 @@ class ProfileManager:
+ ax = fig.add_subplot(111, projection='3d')
+ if len(restrictedBids) == 0:
+ if highlight is None:
+- print "BF:", np_shape(self.transformedCP)
++ print("BF:", np_shape(self.transformedCP))
+ if ignoreContigLengths:
+ sc = ax.scatter(self.transformedCP[:,0],
+ self.transformedCP[:,1],
+@@ -895,7 +895,7 @@ class ProfileManager:
+ marker='.')
+ sc.set_edgecolors = sc.set_facecolors = lambda *args:None # disable depth transparency effect
+
+- print np_shape(disp_vals), np_shape(hide_vals), np_shape(self.transformedCP)
++ print(np_shape(disp_vals), np_shape(hide_vals), np_shape(self.transformedCP))
+
+ # render color bar
+ cbar = plt.colorbar(sc, shrink=0.5)
+@@ -914,7 +914,7 @@ class ProfileManager:
+ r_cols = np_append(r_cols, self.contigGCs[i])
+ num_added += 1
+ r_trans = np_reshape(r_trans, (num_added,3))
+- print np_shape(r_trans)
++ print(np_shape(r_trans))
+ #r_cols = np_reshape(r_cols, (num_added,3))
+ sc = ax.scatter(r_trans[:,0],
+ r_trans[:,1],
+@@ -958,13 +958,13 @@ class ProfileManager:
+ fig.set_size_inches(primaryWidth,primaryWidth)
+ plt.savefig(fileName,dpi=dpi,format=format)
+ except:
+- print "Error saving image",fileName, exc_info()[0]
++ print("Error saving image",fileName, exc_info()[0])
+ raise
+ elif(show):
+ try:
+ plt.show()
+ except:
+- print "Error showing image", exc_info()[0]
++ print("Error showing image", exc_info()[0])
+ raise
+ if del_fig:
+ plt.close(fig)
+@@ -1075,13 +1075,13 @@ class ProfileManager:
+ fig.set_size_inches(primaryWidth,primaryWidth)
+ plt.savefig(fileName,dpi=dpi,format=format)
+ except:
+- print "Error saving image",fileName, exc_info()[0]
++ print("Error saving image",fileName, exc_info()[0])
+ raise
+ else:
+ try:
+ plt.show()
+ except:
+- print "Error showing image", exc_info()[0]
++ print("Error showing image", exc_info()[0])
+ raise
+
+ ###############################################################################
+--- groopm/refine.py.orig 2014-11-26 01:01:33 UTC
++++ groopm/refine.py
+@@ -87,11 +87,11 @@ from scipy.spatial import KDTree as kdt
+ from scipy.spatial.distance import cdist, squareform, pdist
+
+ # GroopM imports
+-from binManager import BinManager
+-from ellipsoid import EllipsoidTool
+-from PCA import PCA, Center
+-import groopmExceptions as ge
+-from som import SOM
++from .binManager import BinManager
++from .ellipsoid import EllipsoidTool
++from .PCA import PCA, Center
++from . import groopmExceptions as ge
++from .som import SOM
+ np_seterr(all='raise')
+
+ ###############################################################################
+@@ -150,23 +150,23 @@ class RefineEngine:
+ ignoreRanges=True
+
+ if auto:
+- print " Start automatic bin refinement"
+- num_binned = len(self.PM.binnedRowIndices.keys())
++ print(" Start automatic bin refinement")
++ num_binned = len(list(self.PM.binnedRowIndices.keys()))
+ perc = "%.2f" % round((float(num_binned)/float(self.PM.numContigs))*100,2)
+- print " ",num_binned,"contigs across",len(self.BM.bins.keys()),"cores (",perc,"% )"
++ print(" ",num_binned,"contigs across",len(list(self.BM.bins.keys())),"cores (",perc,"% )")
+
+ graph = self.autoRefineBins(timer, makeGraph=gf!="")
+ if graph is not None:
+- print " Writing graph to:", gf
++ print(" Writing graph to:", gf)
+ try:
+ with open(gf, "w") as gv_fh:
+ gv_fh.write(graph)
+ except:
+- print "Error writing graph to:", gf
++ print("Error writing graph to:", gf)
+
+- num_binned = len(self.PM.binnedRowIndices.keys())
++ num_binned = len(list(self.PM.binnedRowIndices.keys()))
+ perc = "%.2f" % round((float(num_binned)/float(self.PM.numContigs))*100,2)
+- print " ",num_binned,"contigs across",len(self.BM.bins.keys()),"cores (",perc,"% )"
++ print(" ",num_binned,"contigs across",len(list(self.BM.bins.keys())),"cores (",perc,"% )")
+
+ if plotFinal != "":
+ bids = self.BM.getBids()
+@@ -196,28 +196,28 @@ class RefineEngine:
+ user_option = self.promptOnPlotterRefine()
+
+ if(user_option == 'Q'):
+- print '\nBye!'
++ print('\nBye!')
+ return
+
+ elif(user_option == 'C'):
+- print "Select colormap:"
+- print " 1. HSV"
+- print " 2. Accent"
+- print " 3. Blues"
+- print " 4. Spectral"
+- print " 5. Grayscale"
+- print " 6. Discrete (14 colors)"
+- print " 7. Discrete paired (14 colors)"
++ print("Select colormap:")
++ print(" 1. HSV")
++ print(" 2. Accent")
++ print(" 3. Blues")
++ print(" 4. Spectral")
++ print(" 5. Grayscale")
++ print(" 6. Discrete (14 colors)")
++ print(" 7. Discrete paired (14 colors)")
+
+ bValid = False
+ while(not bValid):
+ try:
+- colormap_id = int(raw_input(" Enter colormap number (e.g., 1): "))
++ colormap_id = int(input(" Enter colormap number (e.g., 1): "))
+ if colormap_id < 1 or colormap_id > 7:
+ raise ValueError('Invalid colormap id.')
+ bValid = True
+ except ValueError:
+- print "Colormap must be specified as a number between 1 and 7."
++ print("Colormap must be specified as a number between 1 and 7.")
+
+ if colormap_id == 1:
+ self.PM.setColorMap('HSV')
+@@ -238,19 +238,19 @@ class RefineEngine:
+ if use_elipses:
+ ET = None
+ use_elipses = False
+- print "\nEllipses off"
++ print("\nEllipses off")
+ else:
+ ET = self.ET
+ use_elipses = True
+- print "\nEllipses on"
++ print("\nEllipses on")
+
+ elif(user_option == 'X'):
+ if show_chimeric_bins:
+ show_chimeric_bins = False
+- print "\nHiding likely chimeric bins."
++ print("\nHiding likely chimeric bins.")
+ else:
+ show_chimeric_bins = True
+- print "\nShowing likely chimeric bins."
++ print("\nShowing likely chimeric bins.")
+
+ elif(user_option == 'R'):
+ self.BM.plotBinIds(ignoreRanges=ignoreRanges, showChimeric=show_chimeric_bins)
+@@ -277,7 +277,7 @@ class RefineEngine:
+ have_range = False
+ while(not have_range):
+ try:
+- gc_range_str = raw_input(" Enter GC range to examine (e.g., 0.5-0.6): ")
++ gc_range_str = input(" Enter GC range to examine (e.g., 0.5-0.6): ")
+
+ if '-' not in gc_range_str:
+ raise ValueError('Incorrectly formatted GC range.')
+@@ -289,7 +289,7 @@ class RefineEngine:
+
+ have_range = True
+ except ValueError:
+- print "GC ranges must be entered as 'a-b' (e.g., 0.5-0.6)."
++ print("GC ranges must be entered as 'a-b' (e.g., 0.5-0.6).")
+ self.BM.plotBinIds(gc_range=gc_range, ignoreRanges=ignoreRanges)
+
+ elif(user_option == 'B'):
+@@ -299,17 +299,17 @@ class RefineEngine:
+ while(not have_bid):
+ have_bid = True
+ try:
+- usr_bids = raw_input(" Enter 'space' seperated bin id(s) to plot: ")
++ usr_bids = input(" Enter 'space' seperated bin id(s) to plot: ")
+ bids = [int(i) for i in usr_bids.split(" ")]
+ if bids == [-1]:
+ bids = self.BM.getBids()
+ else:
+ for bid in bids:
+ if bid not in self.BM.bins:
+- print "ERROR: Bin %d not found!" % bid
++ print("ERROR: Bin %d not found!" % bid)
+ have_bid &= False
+ except ValueError:
+- print "You need to enter an integer value!"
++ print("You need to enter an integer value!")
+
+ if len(bids) > 0:
+ self.BM.plotSelectBins(bids, plotMers=True, ET=ET)
+@@ -320,22 +320,22 @@ class RefineEngine:
+ have_parts = False
+ while(not have_bid):
+ try:
+- bid = int(raw_input(" Enter bid to split: "))
++ bid = int(input(" Enter bid to split: "))
+ if bid not in self.BM.bins:
+- print "ERROR: Bin %d not found!" % bid
++ print("ERROR: Bin %d not found!" % bid)
+ else:
+ have_bid = True
+ except ValueError:
+- print "You need to enter an integer value!"
++ print("You need to enter an integer value!")
+ while(not have_parts):
+ try:
+- parts = int(raw_input(" Enter number of parts to split into: "))
++ parts = int(input(" Enter number of parts to split into: "))
+ if(parts < 2):
+- print "ERROR: Need to choose 2 or more parts"
++ print("ERROR: Need to choose 2 or more parts")
+ else:
+ have_parts = True
+ except ValueError:
+- print "You need to enter an integer value!"
++ print("You need to enter an integer value!")
+ self.BM.split(bid,
+ parts,
+ mode='kmer',
+@@ -350,23 +350,23 @@ class RefineEngine:
+ have_radius = False
+ while(not have_bid):
+ try:
+- bid = int(raw_input(" Enter bid of interest: "))
++ bid = int(input(" Enter bid of interest: "))
+ if bid not in self.BM.bins:
+- print "ERROR: Bin %d not found!" % bid
++ print("ERROR: Bin %d not found!" % bid)
+ else:
+ have_bid = True
+ except ValueError:
+- print "You need to enter an integer value!"
++ print("You need to enter an integer value!")
+ while(not have_radius):
+ try:
+- usr_radius = raw_input(" Enter radius to select from [default 100]: ")
++ usr_radius = input(" Enter radius to select from [default 100]: ")
+ if usr_radius == "":
+ radius = 100
+ else:
+ radius = int(usr_radius)
+ have_radius = True
+ except ValueError:
+- print "You need to enter an integer value!"
++ print("You need to enter an integer value!")
+
+ # we need to find all points in an area about the centroid of
+ # this bin
+@@ -397,9 +397,9 @@ class RefineEngine:
+ # reshape
+ disp_vals = np_reshape(disp_vals, (num_points, 3))
+
+- print " Points are located in bins:"
++ print(" Points are located in bins:")
+ for seen_bid in seen_bids:
+- print " %d - %d occurances" % (seen_bid, len(seen_bids[seen_bid]))
++ print(" %d - %d occurances" % (seen_bid, len(seen_bids[seen_bid])))
+
+ fig = plt.figure()
+ ax = fig.add_subplot(1,1,1, projection='3d')
+@@ -423,7 +423,7 @@ class RefineEngine:
+ try:
+ plt.show()
+ except:
+- print "Error showing image:", sys.exc_info()[0]
++ print("Error showing image:", sys.exc_info()[0])
+ raise
+ plt.close(fig)
+ del fig
+@@ -459,7 +459,7 @@ class RefineEngine:
+ # identify and remove outlier bins
+ if markLikelyChimeric:
+ nuked = self.markLikelyChimericBins()
+- print " %s" % timer.getTimeStamp()
++ print(" %s" % timer.getTimeStamp())
+ sys_stdout.flush()
+
+ if makeGraph:
+@@ -472,7 +472,7 @@ class RefineEngine:
+ # merge bins together
+ if mergeSimilarBins:
+ self.mergeSimilarBins(graph=graph, verbose=False)
+- print " %s" % timer.getTimeStamp()
++ print(" %s" % timer.getTimeStamp())
+ sys_stdout.flush()
+
+ if plotAfterOB:
+@@ -485,12 +485,12 @@ class RefineEngine:
+ self.PM.contigGCs,
+ self.PM.contigLengths)
+ self.BM.plotBins(FNPrefix="AFTER_OB", ET=self.ET)
+- print " %s" % timer.getTimeStamp()
++ print(" %s" % timer.getTimeStamp())
+ sys_stdout.flush()
+
+ if shuffleRefine:
+ nuked = self.shuffleRefineContigs(timer)
+- print " %s" % timer.getTimeStamp()
++ print(" %s" % timer.getTimeStamp())
+ sys_stdout.flush()
+ if makeGraph:
+ # Make sure we know these guys were deleted
+@@ -501,7 +501,7 @@ class RefineEngine:
+
+ if removeDuds:
+ nuked = self.removeDuds()
+- print " %s" % timer.getTimeStamp()
++ print(" %s" % timer.getTimeStamp())
+ sys_stdout.flush()
+ if makeGraph:
+ # Make sure we know these guys were deleted
+@@ -516,7 +516,7 @@ class RefineEngine:
+ def markLikelyChimericBins(self, verbose=False):
+ """ Identify bins which contain mixed genomes based on GC.
+ Small bins are nuked, large bins are flagged as chimeric. """
+- print " Identifying possible chimeric bins"
++ print(" Identifying possible chimeric bins")
+ sys_stdout.flush()
+
+ # first we need to build a distribution!
+@@ -553,8 +553,8 @@ class RefineEngine:
+ freeBinnedRowIndices=True,
+ saveBins=False)
+
+- print " Identified %d likely chimeric bin(s), removed %d small chimeric bin(s)" % (num_chimeric_bins, len(dead_bins))
+- print " %s" % ",".join(str(u) for u in dead_bins)
++ print(" Identified %d likely chimeric bin(s), removed %d small chimeric bin(s)" % (num_chimeric_bins, len(dead_bins)))
++ print(" %s" % ",".join(str(u) for u in dead_bins))
+ return dead_bins
+
+ def mergeSimilarBins(self, verbose=False, graph=None, silent=False):
+@@ -565,7 +565,7 @@ class RefineEngine:
+ orig_num_bins = len(self.BM.getNonChimericBinIds())
+
+ if not silent:
+- print " Merging similar bins (%d) with kCut %0.2f (+/-%0.3f) cCut %0.2f (+/-%0.3f)" % (orig_num_bins, kCutMedian, kCutStd, cCutMedian, cCutStd)
++ print(" Merging similar bins (%d) with kCut %0.2f (+/-%0.3f) cCut %0.2f (+/-%0.3f)" % (orig_num_bins, kCutMedian, kCutStd, cCutMedian, cCutStd))
+
+ # identify merging groups and then merge them
+ mergers = self.findMergeGroups(kCutMedian, kCutStd, cCutMedian, cCutStd, verbose=verbose)
+@@ -575,7 +575,7 @@ class RefineEngine:
+ bins_removed = self.combineMergers(merge, kCutMedian, kCutStd, cCutMedian, cCutStd, graph=graph)
+ num_bins_removed += len(bins_removed)
+ if not silent:
+- print " Merged %d of %d cores leaving %d cores total" % (num_bins_removed, orig_num_bins, len(self.BM.getNonChimericBinIds()))
++ print(" Merged %d of %d cores leaving %d cores total" % (num_bins_removed, orig_num_bins, len(self.BM.getNonChimericBinIds())))
+
+ return num_bins_removed
+
+@@ -666,10 +666,10 @@ class RefineEngine:
+ common_neighbors = set(cov_neighbor_list).intersection(set(kmer_neighbor_list))
+
+ if verbose:
+- print "++++++++++"
+- print bid, cov_neighbor_list
+- print bid, kmer_neighbor_list
+- print bid, common_neighbors
++ print("++++++++++")
++ print(bid, cov_neighbor_list)
++ print(bid, kmer_neighbor_list)
++ print(bid, common_neighbors)
+
+ # test each neighbor in turn
+ for i, neighbor_index in enumerate(common_neighbors):
+@@ -680,8 +680,8 @@ class RefineEngine:
+ merged_query_bid = merged_bins[merged_query_bid]
+
+ if verbose:
+- print "++++++++++"
+- print base_bid, query_bid, merged_base_bid, merged_query_bid
++ print("++++++++++")
++ print(base_bid, query_bid, merged_base_bid, merged_query_bid)
+ #-----
+ # TIME WASTERS
+
+@@ -689,7 +689,7 @@ class RefineEngine:
+ seen_key = self.BM.makeBidKey(base_bid, query_bid)
+ if(seen_key in processed_pairs or merged_base_bid == merged_query_bid):
+ if verbose:
+- print "TW"
++ print("TW")
+ continue
+ processed_pairs[seen_key] = True
+
+@@ -708,7 +708,7 @@ class RefineEngine:
+ )
+ if lengths_wrong:
+ if verbose:
+- print "LW"
++ print("LW")
+ continue
+
+ #-----
+@@ -719,15 +719,15 @@ class RefineEngine:
+ c_dist_bw = self.cDistBetweenBins(base_bin, query_bin)
+
+ if verbose:
+- print 'k_dist_bw, c_dist_bw'
+- print k_dist_bw, c_dist_bw
+- print '---------------------'
++ print('k_dist_bw, c_dist_bw')
++ print(k_dist_bw, c_dist_bw)
++ print('---------------------')
+
+
+ if k_dist_bw < kCutMedian and c_dist_bw < cCutMedian:
+ if verbose:
+- print 'MERGED'
+- print '---------------------'
++ print('MERGED')
++ print('---------------------')
+
+ if merged_query_bid < merged_base_bid:
+ merged_bins[merged_base_bid] = merged_query_bid
+@@ -773,7 +773,7 @@ class RefineEngine:
+
+ if not INTT:
+ if verbose:
+- print "KINTT"
++ print("KINTT")
+ continue
+ #-----
+ # MINIMUM BOUNDING COVERAGE ELLIPSOID
+@@ -802,7 +802,7 @@ class RefineEngine:
+
+ if not intersects:
+ if verbose:
+- print "CINTT"
++ print("CINTT")
+ continue
+
+ # We only get here if we're going to merge the bins
+@@ -869,7 +869,7 @@ class RefineEngine:
+ cur_bin = self.BM.getBin(cur_bid)
+
+ dists = []
+- for i in xrange(1, len(sorted_bid)):
++ for i in range(1, len(sorted_bid)):
+ frag_bid = sorted_bid[i]
+ frag_bin = self.BM.getBin(frag_bid)
+
+@@ -1069,14 +1069,14 @@ class RefineEngine:
+ iterations=800,
+ silent=silent,
+ weightImgFileNamePrefix=animateFilePrefix)
+- print " --"
+- print " %s" % timer.getTimeStamp()
++ print(" --")
++ print(" %s" % timer.getTimeStamp())
+ if render:
+ SS.renderWeights("S1")
+
+ if maskBoundaries:
+ if not silent:
+- print " Creating boundary mask"
++ print(" Creating boundary mask")
+ # make a boundary mask
+ if render:
+ SS.makeBoundaryMask(plotMaskFile="S2.png")
+@@ -1086,23 +1086,23 @@ class RefineEngine:
+ if defineBins:
+ # assign regions on som surface to specific bins
+ if not silent:
+- print " Defining bin regions"
++ print(" Defining bin regions")
+ SS.defineBinRegions(bids, training_data, render=render)
+ if render:
+ SS.renderBoundaryMask("S5.png")
+ if maskBoundaries:
+ # mask out regions where we don't like it
+ if not silent:
+- print " Masking SOM classifier"
++ print(" Masking SOM classifier")
+ SS.maskBoundaries(addNoise=False, doFlat=True)
+ if render:
+ SS.renderWeights("S6")
+
+- print " %s" % timer.getTimeStamp()
++ print(" %s" % timer.getTimeStamp())
+ if retrain:
+ # retrain bin regions using contigs from the bin
+ if not silent:
+- print " Retraining SOM classifier"
++ print(" Retraining SOM classifier")
+ for i in range(len(bids)):
+ bid = bids[i]
+ sys_stdout.write("\r Retraining on bin: %d (%d of %d)" % (bid, i+1, len(bids)))
+@@ -1117,7 +1117,7 @@ class RefineEngine:
+ render=render)
+ if render:
+ SS.renderWeights("gg")
+- print " --"
++ print(" --")
+
+ if render:
+ SS.renderWeights("S7")
+@@ -1148,8 +1148,8 @@ class RefineEngine:
+
+ # now we'd like to centre the weights and mask within an
+ # appropriately sized square
+- min_p = np_min(maskPoints.keys(), axis=0)
+- max_p = np_max(maskPoints.keys(), axis=0)
++ min_p = np_min(list(maskPoints.keys()), axis=0)
++ max_p = np_max(list(maskPoints.keys()), axis=0)
+ diffs = max_p - min_p
+ small_side = np_min(diffs)
+ sweights = np_copy(SS.weights.nodes[min_p[0]:min_p[0]+diffs[0]+1,min_p[1]:min_p[1]+diffs[1]+1])
+@@ -1158,7 +1158,7 @@ class RefineEngine:
+ # shift and mask out all other bins
+ shifted_mask_points = {}
+ shifted_bin_mask = np_ones((diffs[0]+1,diffs[1]+1))
+- for (r,c) in maskPoints.keys():
++ for (r,c) in list(maskPoints.keys()):
+ shift = maskPoints[(r,c)] - min_p
+ shifted_bin_mask[shift[0],shift[1]] = 0
+ shifted_mask_points[(shift[0], shift[1])] = shift
+@@ -1174,7 +1174,7 @@ class RefineEngine:
+
+ #SS.weights.renderSurface("D_%d.png"%bid, nodes=sweights)
+ # update the torusMesh values appropriately
+- for (r,c) in maskPoints.keys():
++ for (r,c) in list(maskPoints.keys()):
+ shift = maskPoints[(r,c)] - min_p
+ SS.weights.nodes[r,c] = sweights[shift[0], shift[1]]
+ SS.weights.fixFlatNodes()
+@@ -1185,7 +1185,7 @@ class RefineEngine:
+
+ def shuffleRefineContigs(self, timer, inclusivity=2):
+ """refine bins by shuffling contigs around"""
+- print " Start shuffle refinement"
++ print(" Start shuffle refinement")
+
+ # first, build a SOM
+ bids = self.BM.getBids()
+@@ -1198,7 +1198,7 @@ class RefineEngine:
+ defineBins=True,
+ retrain=True)
+
+- print " %s" % timer.getTimeStamp()
++ print(" %s" % timer.getTimeStamp())
+
+ # now do the shuffle refinement, keep an eye out for
+ new_assignments = {}
+@@ -1280,30 +1280,30 @@ class RefineEngine:
+ nones[old_bid] = 1
+
+
+- if False:
+- print " ------------------------------------------------------"
+- print " BID ORIG CHGE SAME NEWS NONE TOTAL"
+- print " ------------------------------------------------------"
++ if False:
++ print(" ------------------------------------------------------")
++ print(" BID ORIG CHGE SAME NEWS NONE TOTAL")
++ print(" ------------------------------------------------------")
+ for bid in bids:
+- print " %4d %5d " % (bid, self.BM.bins[bid].binSize),
++ print(" %4d %5d " % (bid, self.BM.bins[bid].binSize), end=' ')
+ if bid in wrongs:
+- print "%04d " % wrongs[bid],
++ print("%04d " % wrongs[bid], end=' ')
+ else:
+- print "0000 ",
++ print("0000 ", end=' ')
+ if bid in rights:
+- print "%04d " % rights[bid],
++ print("%04d " % rights[bid], end=' ')
+ else:
+- print "0000 ",
++ print("0000 ", end=' ')
+ if bid in news:
+- print "%04d " % news[bid],
++ print("%04d " % news[bid], end=' ')
+ else:
+- print "0000 ",
++ print("0000 ", end=' ')
+ if bid in nones:
+- print "%04d " % nones[bid],
++ print("%04d " % nones[bid], end=' ')
+ else:
+- print "0000 ",
+- print "%04d " % len(new_assignments[bid])
+- print "\n ---------------------------------------------"
++ print("0000 ", end=' ')
++ print("%04d " % len(new_assignments[bid]))
++ print("\n ---------------------------------------------")
+
+ # now get ready for saving.
+ # first, we nuke all non-chimeric bins
+@@ -1335,7 +1335,7 @@ class RefineEngine:
+
+ def removeDuds(self, ms=20, mv=1000000, verbose=False):
+ """Run this after refining to remove scrappy leftovers"""
+- print " Removing dud cores (min %d contigs or %d bp)" % (ms, mv)
++ print(" Removing dud cores (min %d contigs or %d bp)" % (ms, mv))
+ deleters = []
+ for bid in self.BM.getBids():
+ self.BM.bins[bid]
+@@ -1343,13 +1343,13 @@ class RefineEngine:
+ # delete this chap!
+ deleters.append(bid)
+ if verbose:
+- print "duds", deleters
++ print("duds", deleters)
+ if len(deleters) > 0:
+ self.BM.deleteBins(deleters,
+ force=True,
+ freeBinnedRowIndices=True,
+ saveBins=False)
+- print " Removed %d cores leaving %d cores" % (len(deleters), len(self.BM.bins))
++ print(" Removed %d cores leaving %d cores" % (len(deleters), len(self.BM.bins)))
+ return deleters
+
+ #------------------------------------------------------------------------------
+@@ -1509,7 +1509,7 @@ class RefineEngine:
+ step_size = float(len(row_indices)) / sample_size
+ si = []
+ index = 0.0
+- for _i in xrange(0, sample_size):
++ for _i in range(0, sample_size):
+ si.append(row_indices[sorted_indices[int(index)]])
+ index += step_size
+
+@@ -1568,10 +1568,10 @@ class RefineEngine:
+ indices2 = bin2.rowIndices
+
+ angles = []
+- for i in xrange(0, min(len(bin1.rowIndices), max_in_bin)):
++ for i in range(0, min(len(bin1.rowIndices), max_in_bin)):
+ r1 = indices1[i]
+
+- for j in xrange(0, min(len(bin2.rowIndices), max_in_bin)):
++ for j in range(0, min(len(bin2.rowIndices), max_in_bin)):
+ r2 = indices2[j]
+ try:
+ ang = np_arccos(np_dot(self.PM.covProfiles[r1], self.PM.covProfiles[r2]) /
+@@ -2051,7 +2051,7 @@ class RefineEngine:
+
+ def recruitWrapper(self, timer, inclusivity=2, step=200, nukeAll=False, saveBins=False):
+ """Recuit more contigs to the bins"""
+- print "Recruiting unbinned contigs"
++ print("Recruiting unbinned contigs")
+
+ # make a list of all the cov and kmer vals
+ total_expanded = 0
+@@ -2090,9 +2090,9 @@ class RefineEngine:
+
+ # talk to the user
+ perc_binned = float(total_binned)/float(total_contigs)
+- print " Planned steps = ", steps
+- print " BEGIN: %0.4f" % perc_binned +"%"+" of %d requested contigs in bins" % total_contigs
+- print " %d contigs unbinned" % total_unbinned
++ print(" Planned steps = ", steps)
++ print(" BEGIN: %0.4f" % perc_binned +"%"+" of %d requested contigs in bins" % total_contigs)
++ print(" %d contigs unbinned" % total_unbinned)
+
+ # build the classifier on all the existing bins
+ (SS, minz, maxz, side) = self.buildSOM(timer,
+@@ -2100,7 +2100,7 @@ class RefineEngine:
+ defineBins=True,
+ retrain=True)
+
+- print " %s" % timer.getTimeStamp()
++ print(" %s" % timer.getTimeStamp())
+
+ # go through the steps we decided on
+ affected_bids = list(np_copy(self.BM.getBids()))
+@@ -2132,7 +2132,7 @@ class RefineEngine:
+ block -= minz
+ block /= maxz
+
+- print " Recruiting contigs above: %d (%d contigs)" % (cutoff, len(unbinned_rows))
++ print(" Recruiting contigs above: %d (%d contigs)" % (cutoff, len(unbinned_rows)))
+
+ for i in range(len(unbinned_rows)):
+ putative_bid = SS.classifyContig(block[i])
+@@ -2159,21 +2159,21 @@ class RefineEngine:
+ for row_index in new_binned:
+ del unbinned[row_index]
+
+- print " Recruited: %d contigs" % this_step_binned
+- print " %s" % timer.getTimeStamp()
++ print(" Recruited: %d contigs" % this_step_binned)
++ print(" %s" % timer.getTimeStamp())
+ sys_stdout.flush()
+
+ # talk to the user
+ perc_recruited = float(total_expanded)/float(total_unbinned)
+ perc_binned = float(total_binned)/float(total_contigs)
+- print " Recruited %0.4f" % perc_recruited +"%"+" of %d unbinned contigs" % total_unbinned
+- print " END: %0.4f" % perc_binned +"%"+" of %d requested contigs in bins" % total_contigs
+- print " %s" % timer.getTimeStamp()
++ print(" Recruited %0.4f" % perc_recruited +"%"+" of %d unbinned contigs" % total_unbinned)
++ print(" END: %0.4f" % perc_binned +"%"+" of %d requested contigs in bins" % total_contigs)
++ print(" %s" % timer.getTimeStamp())
+ sys_stdout.flush()
+
+ # now save
+ if(saveBins):
+- print "Saving bins"
++ print("Saving bins")
+ self.BM.saveBins()
+
+ #------------------------------------------------------------------------------
+@@ -2183,7 +2183,7 @@ class RefineEngine:
+ """Output a valid graphviz dot file"""
+ op = "digraph refine {\n"
+ # render nodes
+- for bid in graph[0].keys():
++ for bid in list(graph[0].keys()):
+ op += graph[0][bid]
+ # render edges
+ op += "\n".join(graph[1])
+@@ -2191,7 +2191,7 @@ class RefineEngine:
+ return op
+
+ def printRefinePlotterInstructions(self):
+- raw_input( "****************************************************************\n"
++ input( "****************************************************************\n"
+ " REFINING INSTRUCTIONS - PLEASE READ CAREFULLY\n"+
+ "****************************************************************\n"
+ " You have chosen to refine in plotter mode. Congratulations!\n"
+@@ -2201,7 +2201,7 @@ class RefineEngine:
+ " Follow the instructions to merge or split these bins\n\n"
+ " Good Luck!\n\n"
+ " Press return to continue...")
+- print "****************************************************************"
++ print("****************************************************************")
+
+ def promptOnPlotterRefine(self, minimal=False):
+ """Find out what the user wishes to do next when refining bins"""
+@@ -2210,9 +2210,9 @@ class RefineEngine:
+ vrs = ",".join([str.lower(str(x)) for x in valid_responses])
+ while(input_not_ok):
+ if(minimal):
+- option = raw_input(" What next? ("+vrs+") : ")
++ option = input(" What next? ("+vrs+") : ")
+ else:
+- option = raw_input("\n Please choose from the following options:\n" \
++ option = input("\n Please choose from the following options:\n" \
+ "------------------------------------------------------------\n" \
+ " r = plot entire space using bin ids\n" \
+ " p = plot entire space with bins as points\n" \
+@@ -2231,7 +2231,7 @@ class RefineEngine:
+ if(option.upper() in valid_responses):
+ return option.upper()
+ else:
+- print "Error, unrecognised choice '"+option+"'"
++ print("Error, unrecognised choice '"+option+"'")
+ minimal=True
+
+ def PCA2Col(self, PCAs):
+@@ -2409,7 +2409,7 @@ class GrubbsTester:
+ idx = 999
+
+ if verbose:
+- print np_mean(compVals+[maxVal]), np_std(compVals+[maxVal], ddof=1), maxVal, v, idx, self.critVs[idx], v > self.critVs[idx]
++ print(np_mean(compVals+[maxVal]), np_std(compVals+[maxVal], ddof=1), maxVal, v, idx, self.critVs[idx], v > self.critVs[idx])
+
+ return v > self.critVs[idx]
+
+--- groopm/som.py.orig 2014-11-26 01:01:33 UTC
++++ groopm/som.py
+@@ -1,5 +1,5 @@
+ #!/usr/bin/env python
+-from __future__ import division
++
+ ###############################################################################
+ # #
+ # som.py #
+@@ -77,12 +77,13 @@ from math import log, exp
+ import numpy as np
+ from scipy.spatial.distance import cdist
+ from PIL import Image, ImageDraw
++from functools import reduce
+ np.seterr(all='raise')
+
+ # GroopM imports
+-from torusMesh import TorusMesh as TM
+-from rainbow import Rainbow
+-import groopmExceptions as ge
++from .torusMesh import TorusMesh as TM
++from .rainbow import Rainbow
++from . import groopmExceptions as ge
+
+ ###############################################################################
+ ###############################################################################
+@@ -193,7 +194,7 @@ class SOM:
+ # we only need to return a tuple
+ nt = self.makeNTuple(s_bid,q_bid)
+ neighbours[nt] = True
+- return neighbours.keys()
++ return list(neighbours.keys())
+
+ def makeNTuple(self, bid1, bid2):
+ """A way for making standard tuples from bids"""
+@@ -228,7 +229,7 @@ class SOM:
+ """
+
+ if not silent:
+- print " Start SOM training. Side: %d Max: %d iterations" % (self.side, iterations)
++ print(" Start SOM training. Side: %d Max: %d iterations" % (self.side, iterations))
+
+ if radius == 0.0:
+ radius = self.radius
+@@ -376,7 +377,7 @@ class SOM:
+ weights = np.clip(weights + deltasheet[rows:2*rows,cols:2*cols], 0, 1)
+ else:
+ delta_fold = deltasheet[rows:2*rows,cols:2*cols]
+- for (r,c) in mask.keys():
++ for (r,c) in list(mask.keys()):
+ weights[r,c] = np.clip(weights[r,c] + delta_fold[r,c], 0, 1)
+ flat_nodes = weights.reshape((rows*cols, self.dimension))
+
+@@ -386,7 +387,7 @@ class SOM:
+ # make a tmp image, perhaps
+ if(weightImgFileNamePrefix != ""):
+ filename = "%s_%04d.jpg" % (weightImgFileNamePrefix, i)
+- print " writing: %s" % filename
++ print(" writing: %s" % filename)
+ self.weights.renderSurface(filename)
+
+ return weights
+@@ -467,7 +468,7 @@ class SOM:
+ # get all the points within this region
+ points = self.floodFill(startR, startC, self.boundaryMask)
+ collision_bid = 0
+- for (r,c) in points.keys():
++ for (r,c) in list(points.keys()):
+ if self.binAssignments[r,c] != 0:
+ if self.binAssignments[r,c] != bid:
+ # we have already assigned this point to a bin
+@@ -487,7 +488,7 @@ class SOM:
+ # rebuild the mask with a new cutoff
+ mc = mc/2
+ mask = np.copy(self.boundaryMask)
+- for (r,c) in points.keys():
++ for (r,c) in list(points.keys()):
+ if self.VS_flat[r,c] > mc:
+ mask[r,c] = 1.
+ else:
+@@ -497,15 +498,15 @@ class SOM:
+ new_points = self.floodFill(startR, startC, mask)
+ #print len(collision_points.keys()), len(new_points.keys())
+ #print collision_points.keys()[0] in new_points
+- if len(collision_points.keys()) == 0 or len(new_points.keys()) == 0:
++ if len(list(collision_points.keys())) == 0 or len(list(new_points.keys())) == 0:
+ continue
+ # there should be no overlap
+- if collision_points.keys()[0] not in new_points:
++ if list(collision_points.keys())[0] not in new_points:
+ # we have resolved the issue
+ resolved = True
+ # now we need to fix the binAssignments and boundary mask
+ self.boundaryMask = mask
+- for (r,c) in points.keys():
++ for (r,c) in list(points.keys()):
+ if (r,c) in new_points:
+ # assign this point to the new bid
+ self.binAssignments[r,c] = bid
+@@ -517,7 +518,7 @@ class SOM:
+ break
+
+ if not resolved:
+- print "Cannot repair map, bin %d may be incorrectly merged with bin %d" % (bid, collision_bid)
++ print("Cannot repair map, bin %d may be incorrectly merged with bin %d" % (bid, collision_bid))
+ return
+
+ def makeBinMask(self, profile, fileName="", dim=False):
+@@ -526,7 +527,7 @@ class SOM:
+ points = self.floodFill(r, c, self.boundaryMask)
+ if fileName != "":
+ ret_mask = np.ones_like(self.boundaryMask)
+- for (r,c) in points.keys():
++ for (r,c) in list(points.keys()):
+ ret_mask[r,c] = 0
+ self.renderBoundaryMask(fileName, mask=ret_mask)
+
+@@ -600,7 +601,7 @@ class SOM:
+ img = img.resize((self.weights.columns*10, self.weights.rows*10),Image.NEAREST)
+ img.save(filename)
+ except:
+- print sys.exc_info()[0]
++ print(sys.exc_info()[0])
+ raise
+
+ def renderBoundaryMask(self, fileName, mask=None, colMap=None):
+@@ -625,7 +626,7 @@ class SOM:
+ img = img.resize((self.side*10, self.side*10),Image.NEAREST)
+ img.save(fileName)
+ except:
+- print sys.exc_info()[0]
++ print(sys.exc_info()[0])
+ raise
+
+ def transColour(self, val):
+@@ -659,7 +660,7 @@ class SOM:
+ img = img.resize((self.weights.columns*10, self.weights.rows*10),Image.NEAREST)
+ img.save(fileName)
+ except:
+- print sys.exc_info()[0]
++ print(sys.exc_info()[0])
+ raise
+
+ ###############################################################################
+--- groopm/torusMesh.py.orig 2014-11-26 01:01:33 UTC
++++ groopm/torusMesh.py
+@@ -250,7 +250,7 @@ class TorusMesh:
+ img = img.resize((columns*10, rows*10),Image.NEAREST)
+ img.save(fileName)
+ except:
+- print sys.exc_info()[0]
++ print(sys.exc_info()[0])
+ raise
+
+ ###############################################################################