# HG changeset patch # User Martin C. Frith # Date 1510116368 -32400 # Node ID 21fbf377641f0ca1f055bea6c9bd4889e7c4dfca # Parent 8d52cef22afab61d9b1168e72cd0e79720717e57 Refactor last-dotplot diff -r 8d52cef22afa -r 21fbf377641f scripts/last-dotplot --- a/scripts/last-dotplot Wed Nov 08 12:17:50 2017 +0900 +++ b/scripts/last-dotplot Wed Nov 08 13:46:08 2017 +0900 @@ -11,6 +11,7 @@ import gzip from fnmatch import fnmatchcase +from operator import itemgetter import subprocess import itertools, optparse, os, re, sys @@ -213,22 +214,22 @@ '''Return miscellaneous information about the sequences.''' if sortOpt == 1: seqNames.sort(key=natural_sort_key) - seqSizes = [seqLimits[i][1] - seqLimits[i][0] for i in seqNames] + rangeSizes = [seqLimits[i][1] - seqLimits[i][0] for i in seqNames] for i in seqNames: r = seqLimits[i] out = i, str(r[0]), str(r[1]) warn("\t".join(out)) warn("") if sortOpt == 2: - seqRecords = sorted(zip(seqSizes, seqNames), reverse=True) - seqSizes = [i[0] for i in seqRecords] + seqRecords = sorted(zip(rangeSizes, seqNames), reverse=True) + rangeSizes = [i[0] for i in seqRecords] seqNames = [i[1] for i in seqRecords] seqRanges = [(i, seqLimits[i][0], seqLimits[i][1]) for i in seqNames] labelData = list(rangeLabels(seqRanges, labelOpt, font, fontsize, image_mode, textRot)) margin = max(i[2] for i in labelData) # xxx the margin may be too big, because some labels may get omitted - return seqNames, seqSizes, labelData, margin + return seqRanges, rangeSizes, labelData, margin def div_ceil(x, y): '''Return x / y rounded up.''' @@ -488,12 +489,16 @@ draw.text(position, i[3], font=font, fill=opts.text_color) return im -def rangesPerSeq(seqNames, seqLimits, rangePixBegs, bpPerPix): - for i, j in zip(seqNames, rangePixBegs): - beg, end = seqLimits[i] - origin = bpPerPix * j - beg - r = beg, end, origin - yield i, [r] +def rangesWithOrigins(sortedRanges, rangePixBegs, bpPerPix): + for i, j in zip(sortedRanges, rangePixBegs): + seqName, rangeBeg, rangeEnd = i + origin = bpPerPix * j - rangeBeg + yield seqName, (rangeBeg, rangeEnd, origin) + +def rangesPerSeq(sortedRanges, rangePixBegs, bpPerPix): + a = rangesWithOrigins(sortedRanges, rangePixBegs, bpPerPix) + for k, v in itertools.groupby(a, itemgetter(0)): + yield k, [i[1] for i in v] def getFont(opts): if opts.fontfile: @@ -533,12 +538,12 @@ textRot1 = "vertical".startswith(opts.rot1) i1 = getSeqInfo(opts.sort1, seqNames1, seqLimits1, font, opts.fontsize, image_mode, opts.labels1, textRot1) - seqNames1, rangeSizes1, labelData1, tMargin = i1 + sortedRanges1, rangeSizes1, labelData1, tMargin = i1 textRot2 = "horizontal".startswith(opts.rot2) i2 = getSeqInfo(opts.sort2, seqNames2, seqLimits2, font, opts.fontsize, image_mode, opts.labels2, textRot2) - seqNames2, rangeSizes2, labelData2, lMargin = i2 + sortedRanges2, rangeSizes2, labelData2, lMargin = i2 maxPixels1 = opts.width - lMargin maxPixels2 = opts.height - tMargin @@ -549,13 +554,11 @@ p1 = pixelData(rangeSizes1, bpPerPix, opts.border_pixels, lMargin) rangePixBegs1, rangePixLens1, width = p1 - rangeDict1 = dict(rangesPerSeq(seqNames1, seqLimits1, rangePixBegs1, - bpPerPix)) + rangeDict1 = dict(rangesPerSeq(sortedRanges1, rangePixBegs1, bpPerPix)) p2 = pixelData(rangeSizes2, bpPerPix, opts.border_pixels, tMargin) rangePixBegs2, rangePixLens2, height = p2 - rangeDict2 = dict(rangesPerSeq(seqNames2, seqLimits2, rangePixBegs2, - bpPerPix)) + rangeDict2 = dict(rangesPerSeq(sortedRanges2, rangePixBegs2, bpPerPix)) warn("width: " + str(width)) warn("height: " + str(height))