diff --git a/graphicsItems/AxisItem.py b/graphicsItems/AxisItem.py index d6615748..27589636 100644 --- a/graphicsItems/AxisItem.py +++ b/graphicsItems/AxisItem.py @@ -537,6 +537,10 @@ class AxisItem(GraphicsWidget): else: xScale = bounds.width() / dif offset = self.range[0] * xScale + + xRange = [x * xScale - offset for x in self.range] + xMin = min(xRange) + xMax = max(xRange) prof.mark('init') @@ -545,6 +549,7 @@ class AxisItem(GraphicsWidget): ## draw ticks ## (to improve performance, we do not interleave line and text drawing, since this causes unnecessary pipeline switching) ## draw three different intervals, long ticks first + for i in range(len(tickLevels)): tickPositions.append([]) ticks = tickLevels[i][1] @@ -557,7 +562,13 @@ class AxisItem(GraphicsWidget): lineAlpha = self.grid for v in ticks: + ## determine actual position to draw this tick x = (v * xScale) - offset + if x < xMin or x > xMax: ## last check to make sure no out-of-bounds ticks are drawn + tickPositions[i].append(None) + continue + tickPositions[i].append(x) + p1 = [x, x] p2 = [x, x] p1[axis] = tickStart @@ -570,7 +581,6 @@ class AxisItem(GraphicsWidget): tickPen.setColor(color) p.setPen(tickPen) p.drawLine(Point(p1), Point(p2)) - tickPositions[i].append(x) prof.mark('draw ticks') ## Draw text until there is no more room (or no more text) @@ -585,10 +595,15 @@ class AxisItem(GraphicsWidget): if len(strings) == 0: continue + + ## ignore strings belonging to ticks that were previously ignored + for j in range(len(strings)): + if tickPositions[i][j] is None: + strings[j] = None if i > 0: ## always draw top level ## measure all text, make sure there's enough room - textRects.extend([p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, s) for s in strings]) + textRects.extend([p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, s) for s in strings if s is not None]) if axis == 0: textSize = np.sum([r.height() for r in textRects]) else: @@ -603,6 +618,8 @@ class AxisItem(GraphicsWidget): #strings = self.tickStrings(values, self.scale, spacing) for j in range(len(strings)): vstr = strings[j] + if vstr is None:## this tick was ignored because it is out of bounds + continue x = tickPositions[i][j] textRect = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, vstr) height = textRect.height() diff --git a/multiprocess/parallelizer.py b/multiprocess/parallelizer.py index 66f01938..eda82d31 100644 --- a/multiprocess/parallelizer.py +++ b/multiprocess/parallelizer.py @@ -37,7 +37,7 @@ class Parallelize: since it is automatically sent via pipe back to the parent process. """ - def __init__(self, tasks, workers=None, block=True, progressDialog=None, **kwds): + def __init__(self, tasks, workers=None, block=True, progressDialog=None, randomReseed=True, **kwds): """ =============== =================================================================== Arguments: @@ -47,6 +47,9 @@ class Parallelize: system progressDialog optional dict of arguments for ProgressDialog to update while tasks are processed + randomReseed If True, each forked process will reseed its random number generator + to ensure independent results. Works with the built-in random + and numpy.random. kwds objects to be shared by proxy with child processes (they will appear as attributes of the tasker) =============== =================================================================== @@ -68,6 +71,7 @@ class Parallelize: workers = 1 self.workers = workers self.tasks = list(tasks) + self.reseed = randomReseed self.kwds = kwds.copy() self.kwds['_taskStarted'] = self._taskStarted @@ -112,7 +116,7 @@ class Parallelize: ## fork and assign tasks to each worker for i in range(workers): - proc = ForkedProcess(target=None, preProxy=self.kwds) + proc = ForkedProcess(target=None, preProxy=self.kwds, randomReseed=self.reseed) if not proc.isParent: self.proc = proc return Tasker(proc, chunks[i], proc.forkedProxies) @@ -150,7 +154,17 @@ class Parallelize: #print "remove:", [ch.childPid for ch in rem] for ch in rem: activeChilds.remove(ch) - os.waitpid(ch.childPid, 0) + while True: + try: + os.waitpid(ch.childPid, 0) + break + except OSError as ex: + if ex.errno == 4: ## If we get this error, just try again + continue + #print "Ignored system call interruption" + else: + raise + #print [ch.childPid for ch in activeChilds] if self.showProgress and self.progressDlg.wasCanceled():