From dcb555a12ff7811a8a7441d7e1c1a63deec16dee Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Mon, 30 Mar 2020 21:33:52 -0300 Subject: [PATCH 01/26] Initial conversion with 2to3 followed by some manual intervention converting byte strings to unicode --- .../Biophysics/BacterialModels/CLBacterium.py | 58 +- .../GeneralModels/CLFixedPosition.py | 2 +- CellModeller/GUI/PyGLCMViewer.py | 46 +- CellModeller/GUI/PyGLWidget.py | 8 +- CellModeller/GUI/Renderers.py | 1323 ++++++++++++----- .../Integration/CLCrankNicIntegrator.py | 17 +- CellModeller/Integration/CLEulerIntegrator.py | 15 +- .../Integration/CLEulerSigIntegrator.py | 15 +- CellModeller/Regulation/ModuleRegulator.py | 6 +- CellModeller/Regulation/SBMLImport.py | 28 +- CellModeller/Signalling/GridDiffusion.py | 9 +- CellModeller/Signalling/NeighbourDiffusion.py | 4 +- CellModeller/Simulator.py | 52 +- Examples/ACS2012/EdgeDetectorChamber.py | 4 +- Examples/Conjugation.py | 2 +- Examples/TimRudgeThesis/Meristem.py | 4 +- Examples/Tutorial_1/Tutorial_1a.py | 2 +- Examples/Tutorial_1/Tutorial_1b.py | 4 +- Examples/Tutorial_1/Tutorial_1c.py | 2 +- Examples/Tutorial_2/Tutorial_2a.py | 2 +- Examples/Tutorial_2/Tutorial_2b.py | 2 +- Examples/Tutorial_3/Tutorial_3.py | 2 +- Examples/colorWalk_planes_3d.py | 2 +- Examples/ex1_simpleGrowth.py | 4 +- Examples/ex1_simpleGrowth2D.py | 2 +- Examples/ex1a_simpleGrowth2D.py | 2 +- Examples/ex1a_simpleGrowth2Types.py | 2 +- Examples/ex1b_simpleGrowth2D.py | 2 +- Examples/ex1b_simpleGrowthRoundCell.py | 2 +- Examples/ex2_constGene.py | 2 +- Examples/ex2a_dilution.py | 2 +- Examples/ex2b_diluteRepression.py | 2 +- Examples/ex3_simpleSignal.py | 2 +- Examples/ex4_simpleCellCellSignaling.py | 2 +- Examples/ex5_colonySector.py | 2 +- Examples/ex5_colonySector_3d.py | 2 +- Examples/load.py | 12 +- Scripts/CellModellerGUI.py | 4 +- Scripts/Draw2DPDF.py | 20 +- Scripts/LengthHistogram.py | 10 +- Scripts/batch.py | 14 +- Scripts/batchFile.py | 10 +- Scripts/contactGraph.py | 22 +- Scripts/multi_batch.py | 14 +- Scripts/printTiming.py | 10 +- Scripts/spatial_analyze.py | 8 +- setup.py | 4 +- 47 files changed, 1210 insertions(+), 555 deletions(-) diff --git a/CellModeller/Biophysics/BacterialModels/CLBacterium.py b/CellModeller/Biophysics/BacterialModels/CLBacterium.py index 384e3fc7..68afd810 100644 --- a/CellModeller/Biophysics/BacterialModels/CLBacterium.py +++ b/CellModeller/Biophysics/BacterialModels/CLBacterium.py @@ -111,13 +111,13 @@ def addCell(self, cellState, pos=(0,0,0), dir=(1,0,0), rad=0.5, **kwargs): # Eventually prob better to have a generic editCell() that deals with this stuff # def moveCell(self, cellState, delta_pos): - print "cell idx = %d"%cellState.idx + print("cell idx = %d"%cellState.idx) i = cellState.idx cid = cellState.id - print "cell center = " - print self.cell_centers[i] - print "delta_pos" - print delta_pos + print("cell center = ") + print(self.cell_centers[i]) + print("delta_pos") + print(delta_pos) pos = numpy.array(tuple(self.cell_centers[i])) pos[0:3] += numpy.array(tuple(delta_pos)) self.cell_centers[i] = pos @@ -149,7 +149,7 @@ def init_cl(self): def init_kernels(self): """Set up the OpenCL kernels.""" from pkg_resources import resource_string - kernel_src = resource_string(__name__, 'CLBacterium.cl') + kernel_src = resource_string(__name__, 'CLBacterium.cl').decode() self.program = cl.Program(self.context, kernel_src).build(cache_dir=False) # Some kernels that seem like they should be built into pyopencl... @@ -287,7 +287,7 @@ def init_data(self): def load_from_cellstates(self, cell_states): - for (cid,cs) in cell_states.items(): + for (cid,cs) in list(cell_states.items()): i = cs.idx self.cell_centers[i] = tuple(cs.pos)+(0,) self.cell_dirs[i] = tuple(cs.dir)+(0,) @@ -301,10 +301,10 @@ def load_from_cellstates(self, cell_states): def load_test_data(self): import CellModeller.Biophysics.BacterialModels.CLData as data - self.cell_centers.put(range(len(data.pos)), data.pos) - self.cell_dirs.put(range(len(data.dirs)), data.dirs) - self.cell_lens.put(range(len(data.lens)), data.lens) - self.cell_rads.put(range(len(data.rads)), data.rads) + self.cell_centers.put(list(range(len(data.pos))), data.pos) + self.cell_dirs.put(list(range(len(data.dirs))), data.dirs) + self.cell_lens.put(list(range(len(data.lens))), data.lens) + self.cell_rads.put(list(range(len(data.rads))), data.rads) self.n_cells = data.n_cells self.set_cells() @@ -455,13 +455,13 @@ def matrixTest(self): if ii!=self.n_cells-1 or jj!=6: opstring = opstring + '\t' opstring = opstring + '\n' - print "MTM" - print opstring + print("MTM") + print(opstring) open('CellModeller/Biophysics/BacterialModels/matrix.mat', 'w').write(opstring) def dump_cell_data(self, n): - import cPickle + import pickle filename = 'data/data-%04i.pickle'%n outfile = open(filename, 'wb') data = (self.n_cells, @@ -470,7 +470,7 @@ def dump_cell_data(self, n): self.cell_lens_dev.get(), self.cell_rads_dev.get(), self.parents), - cPickle.dump(data, outfile, protocol=-1) + pickle.dump(data, outfile, protocol=-1) def dydt(self): self.set_cells() @@ -479,7 +479,7 @@ def finish(self): # pull cells from the device and update simulator if self.simulator: self.get_cells() - for state in self.simulator.cellStates.values(): + for state in list(self.simulator.cellStates.values()): self.updateCellState(state) def progress_init(self, dt): @@ -508,7 +508,7 @@ def progress_finalise(self): self.minutes_elapsed = (numpy.float32(self.seconds_elapsed) / 60.0) self.hours_elapsed = (numpy.float32(self.minutes_elapsed) / 60.0) if self.frame_no % 10 == 0: - print '% 8i % 8i cells % 8i contacts %f hour(s) or %f minute(s) or %f second(s)' % (self.frame_no, self.n_cells, self.n_cts, self.hours_elapsed, self.minutes_elapsed, self.seconds_elapsed) + print('% 8i % 8i cells % 8i contacts %f hour(s) or %f minute(s) or %f second(s)' % (self.frame_no, self.n_cells, self.n_cts, self.hours_elapsed, self.minutes_elapsed, self.seconds_elapsed)) # pull cells from the device and update simulator if self.simulator: self.get_cells() @@ -517,7 +517,7 @@ def progress_finalise(self): # TJR: add flag for this cos a bit time consuming if self.computeNeighbours: self.updateCellNeighbours(self.simulator.idxToId) - for state in self.simulator.cellStates.values(): + for state in list(self.simulator.cellStates.values()): self.updateCellState(state) def step(self, dt): @@ -926,8 +926,8 @@ def CGSSolve(self, dt, substep=False): rsfirst = rsold if math.sqrt(rsold/self.n_cells) < self.cgs_tol: if self.printing and self.frame_no%10==0: - print '% 5i'%self.frame_no + '% 6i cells % 6i cts % 6i iterations residual = %f' % (self.n_cells, - self.n_cts, 0, rsold) + print('% 5i'%self.frame_no + '% 6i cells % 6i cts % 6i iterations residual = %f' % (self.n_cells, + self.n_cts, 0, rsold)) return (0.0, rsold) # iterate @@ -970,7 +970,7 @@ def CGSSolve(self, dt, substep=False): #print ' ',iter,rsold if self.printing and self.frame_no%10==0: - print '% 5i'%self.frame_no + '% 6i cells % 6i cts % 6i iterations residual = %f' % (self.n_cells, self.n_cts, iter+1, rsnew) + print('% 5i'%self.frame_no + '% 6i cells % 6i cts % 6i iterations residual = %f' % (self.n_cells, self.n_cts, iter+1, rsnew)) return (iter+1, math.sqrt(rsnew/self.n_cells)) @@ -1062,14 +1062,18 @@ def divide_cell(self, i, d1i, d2i): if not self.jitter_z: jitter[2] = 0.0 cdir[0:3] += jitter cdir /= numpy.linalg.norm(cdir) - self.cell_dirs[a] = cdir + self.cell_dirs[a][0] = cdir[0] + self.cell_dirs[a][1] = cdir[1] + self.cell_dirs[a][2] = cdir[2] cdir = numpy.array(parent_dir) jitter = numpy.random.uniform(-0.001,0.001,3) if not self.jitter_z: jitter[2] = 0.0 cdir[0:3] += jitter cdir /= numpy.linalg.norm(cdir) - self.cell_dirs[b] = cdir + self.cell_dirs[b][0] = cdir[0] + self.cell_dirs[b][1] = cdir[1] + self.cell_dirs[b][2] = cdir[2] else: cdir = numpy.array(parent_dir) tmp = cdir[0] @@ -1141,7 +1145,7 @@ def profileGrid(self): self.sorted_ids_dev.set(self.sorted_ids) # push changes to the device self.sq_inds_dev.set(self.sq_inds) t2 = time.clock() - print "Grid stuff timing for 1000 calls, time per call (s) = %f"%((t2-t1)*0.001) + print("Grid stuff timing for 1000 calls, time per call (s) = %f"%((t2-t1)*0.001)) open("grid_prof","a").write( "%i, %i, %f\n"%(self.n_cells,self.n_cts,(t2-t1)*0.001) ) @@ -1167,7 +1171,7 @@ def profileFindCts(self): self.compact_cts() self.ct_inds_dev.set(self.ct_inds) t2 = time.clock() - print "Find contacts timing for 1000 calls, time per call (s) = %f"%((t2-t1)*0.001) + print("Find contacts timing for 1000 calls, time per call (s) = %f"%((t2-t1)*0.001)) open("findcts_prof","a").write( "%i, %i, %f\n"%(self.n_cells,self.n_cts,(t2-t1)*0.001) ) def profileCGS(self): @@ -1179,9 +1183,9 @@ def profileCGS(self): for i in range(1000): self.build_matrix(dt) # Calculate entries of the matrix (iters, res) = self.CGSSolve() - print "cgs prof: iters=%i, res=%f"%(iters,res) + print("cgs prof: iters=%i, res=%f"%(iters,res)) t2 = time.clock() - print "CGS timing for 1000 calls, time per call (s) = %f"%((t2-t1)*0.001) + print("CGS timing for 1000 calls, time per call (s) = %f"%((t2-t1)*0.001)) open("cgs_prof","a").write( "%i, %i, %i, %f\n"%(self.n_cells,self.n_cts,iters,(t2-t1)*0.001) ) diff --git a/CellModeller/Biophysics/GeneralModels/CLFixedPosition.py b/CellModeller/Biophysics/GeneralModels/CLFixedPosition.py index a7186752..87d6e7cf 100644 --- a/CellModeller/Biophysics/GeneralModels/CLFixedPosition.py +++ b/CellModeller/Biophysics/GeneralModels/CLFixedPosition.py @@ -81,7 +81,7 @@ def step(self, dt): if self.simulator: self.get_cells() - for state in self.simulator.cellStates.values(): + for state in list(self.simulator.cellStates.values()): self.updateCellState(state) return True diff --git a/CellModeller/GUI/PyGLCMViewer.py b/CellModeller/GUI/PyGLCMViewer.py index f41be43d..8ab6babe 100644 --- a/CellModeller/GUI/PyGLCMViewer.py +++ b/CellModeller/GUI/PyGLCMViewer.py @@ -1,8 +1,9 @@ -import PyQt4 -from PyQt4 import QtCore, QtGui -from PyQt4.Qt import Qt -from PyQt4.QtCore import QObject, QTimer, pyqtSignal, pyqtSlot, QStringList -from PyGLWidget import PyGLWidget +import PyQt5 +from PyQt5 import QtCore, QtGui +from PyQt5.Qt import Qt +from PyQt5.QtCore import QObject, QTimer, pyqtSignal, pyqtSlot +from PyQt5.QtWidgets import QInputDialog, QFileDialog +from .PyGLWidget import PyGLWidget from OpenGL.GL import * from OpenGL.GLU import * @@ -11,8 +12,9 @@ from CellModeller.CellState import CellState import os import sys -import cPickle +import pickle import pyopencl as cl +import importlib class PyGLCMViewer(PyGLWidget): @@ -62,20 +64,20 @@ def getOpenCLPlatform(self): # Pop dialogs to get user to choose OpenCL platform platforms = cl.get_platforms() - platlist = QStringList([str(p.name) for p in platforms]) - platdict = dict(zip(platlist, range(len(platlist)))) + platlist = [str(p.name) for p in platforms] + platdict = dict(list(zip(platlist, list(range(len(platlist)))))) if len(platlist)==1: self.clPlatformNum = 0 return True - qsPlatformName, ok = QtGui.QInputDialog.getItem(self, \ + qsPlatformName, ok = QInputDialog.getItem(self, \ 'Choose OpenCL platform', \ 'Available platforms:', \ platlist, \ editable=False) if not ok: - print "You didn't select a OpenCL platform..." + print("You didn't select a OpenCL platform...") return False else: self.clPlatformNum = platdict[qsPlatformName] @@ -86,20 +88,20 @@ def getOpenCLDevice(self): platforms = cl.get_platforms() devices = platforms[self.clPlatformNum].get_devices() - devlist = QStringList([str(d.name) for d in devices]) - devdict = dict(zip(devlist, range(len(devlist)))) + devlist = [str(d.name) for d in devices] + devdict = dict(list(zip(devlist, list(range(len(devlist)))))) if len(devlist)==1: self.clDeviceNum = 0 return True - qsDeviceName, ok = QtGui.QInputDialog.getItem(self, \ + qsDeviceName, ok = QInputDialog.getItem(self, \ 'Choose OpenCL device', \ 'Available devices:', \ devlist, \ editable=False) if not ok: - print "You didn't select a OpenCL device..." + print("You didn't select a OpenCL device...") return False else: self.clDeviceNum = devdict[qsDeviceName] @@ -121,7 +123,7 @@ def toggleSavePickles(self, save): def reset(self): # Note: we don't ask user to choose OpenCL platform/device on reset, only load if not self.loadingFromPickle: - reload(self.sim.module) + importlib.reload(self.sim.module) if self.loadingFromPickle: sim = Simulator(self.modName, \ @@ -143,10 +145,10 @@ def reset(self): @pyqtSlot() def loadPickle(self): - qs = QtGui.QFileDialog.getOpenFileName(self, 'Load pickle file', '', '*.pickle') + qs = QFileDialog.getOpenFileName(self, 'Load pickle file', '', '*.pickle') if qs and self.getOpenCLPlatDev(): filename = str(qs) - data = cPickle.load(open(filename,'rb')) + data = pickle.load(open(filename,'rb')) if isinstance(data, dict): self.modName = data['moduleName'] self.moduleStr = data['moduleStr'] @@ -168,11 +170,11 @@ def loadPickle(self): self.frameNo += 1 self.updateGL() else: - print "Pickle is in an unsupported format, sorry" + print("Pickle is in an unsupported format, sorry") @pyqtSlot() def load(self): - qs = QtGui.QFileDialog.getOpenFileName(self, 'Load Python module', '', '*.py') + qs = QFileDialog.getOpenFileName(self, 'Load Python module', '', '*.py') if qs: modfile = str(qs) self.loadModelFile(modfile) @@ -206,10 +208,10 @@ def updateSelectedCell(self): states = self.sim.cellStates cid = self.selectedName txt = '' - if states.has_key(cid): + if cid in states: txt += 'Selected Cell (id = %d)\n---\n'%(cid) s = states[cid] - for (name,val) in s.__dict__.items(): + for (name,val) in list(s.__dict__.items()): if name not in CellState.excludeAttr: txt += name + ': ' txt += str(val) @@ -228,7 +230,7 @@ def translate(self, _trans): # currently the translation is not great due to the way PyGLWidget works if False: #self.sim and self.sim.cellStates.has_key(cid): self.sim.moveCell(cid, _trans) - print "Called self.sim.moveCell" + print("Called self.sim.moveCell") self.updateSelectedCell() else: # Translate the object by _trans diff --git a/CellModeller/GUI/PyGLWidget.py b/CellModeller/GUI/PyGLWidget.py index 726e939b..628ed0b7 100644 --- a/CellModeller/GUI/PyGLWidget.py +++ b/CellModeller/GUI/PyGLWidget.py @@ -32,7 +32,7 @@ # #=============================================================================== -from PyQt4 import QtCore, QtGui, QtOpenGL +from PyQt5 import QtCore, QtGui, QtOpenGL import math import numpy import numpy.linalg as linalg @@ -74,7 +74,7 @@ def __init__(self, parent = None): @QtCore.pyqtSlot() def printModelViewMatrix(self): - print self.modelview_matrix_ + print(self.modelview_matrix_) def initializeGL(self): # OpenGL state @@ -219,7 +219,7 @@ def map_to_sphere(self, _v2D): def wheelEvent(self, _event): # Use the mouse wheel to zoom in/out - d = - float(_event.delta()) / 200.0 * self.radius_ + d = - float(_event.angleDelta().y()) / 200.0 * self.radius_ self.translate([0.0, 0.0, d]) self.updateGL() _event.accept() @@ -282,7 +282,7 @@ def mouseMoveEvent(self, _event): # move in z direction if (((_event.buttons() & QtCore.Qt.LeftButton) and (_event.buttons() & QtCore.Qt.MidButton)) or (_event.buttons() & QtCore.Qt.LeftButton and _event.modifiers() & QtCore.Qt.ControlModifier)): - print "translating in Z" + print("translating in Z") value_y = self.radius_ * dy * 2.0 / h self.translate([0.0, 0.0, value_y]) # move in x,y direction diff --git a/CellModeller/GUI/Renderers.py b/CellModeller/GUI/Renderers.py index 74878cf1..52a6501c 100644 --- a/CellModeller/GUI/Renderers.py +++ b/CellModeller/GUI/Renderers.py @@ -3,16 +3,15 @@ from OpenGL.arrays import vbo import math import numpy -import numpy.linalg as la import random +#import pygame # helper module for text rendering - turned off to see if it suppresses segfaults +#from pyopencl.array import vec class GLGridRenderer: - def __init__(self, sig, integ, rng=None, alpha=0.5): + def __init__(self, sig, integ, rng=None): self.sig = sig self.integ = integ self.rng = rng - self.alpha = alpha - self.size = self.sig.gridSize self.dim = self.sig.gridDim[1:] self.len = self.dim[0]*self.dim[1] @@ -45,16 +44,15 @@ def render_gl(self, selection=None): mx = numpy.max(self.imageData) mn = numpy.min(self.imageData) if mx>mn: - scale = 255.0/(mx-mn) + scale = 255/(mx-mn) else: - scale = 1.0 - #print "mx = %f, mn = %f, scale = %f"%(mx,mn,scale) - self.imageData = numpy.clip((self.imageData - mn)*scale, 0.0, 255.0) + scale = 1 + self.imageData = (self.imageData - mn)*scale #print "Signal grid range = %f to %f"%(mn,mx) for s in range(self.sig.nSignals): self.byteImageData[0:self.dim[0],0:self.dim[1],s] = self.imageData[s,:,:].astype(numpy.uint8) - glDisable(GL_CULL_FACE) + glEnable(GL_TEXTURE_2D) glDisable(GL_LIGHTING) glDisable(GL_DEPTH_TEST) @@ -62,13 +60,13 @@ def render_gl(self, selection=None): #Load the Data into the Texture glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, self.texDim, self.texDim, 0, GL_RGB, GL_UNSIGNED_BYTE, self.byteImageData ) # glTexSubImage2Dub( GL_TEXTURE_2D, 0, 0,0, GL_RED, GL_UNSIGNED_BYTE, self.imageData ) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)#GL_LINEAR) + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)#GL_LINEAR) #Define some Parameters for this Texture glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glColor4f(1.0,1.0,1.0,self.alpha) + glColor4f(1.0,1.0,1.0,0.2) glBegin(GL_QUADS) glTexCoord2f(0.0, 0.0) glVertex3f(self.orig[0], self.orig[1], 0.0) # Bottom Left Of The Texture and Quad @@ -91,36 +89,36 @@ def __init__(self, sim, chanIdx): self.wallcol = [0, 0, 0] self.nodecol = [0, 0, 0] self.cellcol = [1, 1, 1] - self.chanIdx = chanIdx + self.chanIdx = chanIdx def init_gl(self): pass def renderNames_gl(self): - pass + pass def render_gl(self, selection=None): - # Render signals[chanIdx] as rgb - # - maxSig = [0,0,0] + # Render signals[chanIdx] as rgb + # + maxSig = [0,0,0] for i in range(len(self.chanIdx)): for (cid,cellState) in self.sim.cellStates.items(): - s = cellState.signals[self.chanIdx[i]] - if s > maxSig[i]: - maxSig[i] = s - if maxSig[i]==0: - maxSig[i]=1.0 - - for (cid,cellState) in self.sim.cellStates.items(): - col = [0,0,0] - for i in range(len(self.chanIdx)): - col[i] = cellState.signals[self.chanIdx[i]]/maxSig[i] - glColor3fv(col) - glBegin(GL_POLYGON) - for p in cellState.nodep: - glVertex2d(p[0], p[1]) - glEnd() - + s = cellState.signals[self.chanIdx[i]] + if s > maxSig[i]: + maxSig[i] = s + if maxSig[i]==0: + maxSig[i]=1.0 + + for (cid,cellState) in self.sim.cellStates.items(): + col = [0,0,0] + for i in range(len(self.chanIdx)): + col[i] = cellState.signals[self.chanIdx[i]]/maxSig[i] + glColor3fv(col) + glBegin(GL_POLYGON) + for p in cellState.nodep: + glVertex2d(p[0], p[1]) + glEnd() + class GLPlantRenderer: def __init__(self, sim): self.sim = sim @@ -132,8 +130,8 @@ def init_gl(self): pass def renderNames_gl(self): - # Render cell_ids for selection - # + # Render cell_ids for selection + # for (cid,cellState) in self.sim.cellStates.items(): glColor3fv(self.cellcol) glPushName(cid) @@ -141,11 +139,11 @@ def renderNames_gl(self): for p in cellState.nodep: glVertex2d(p[0], p[1]) glEnd() - glPopName() + glPopName() def render_gl(self, selection=None): # Render model using PyOpenGL - # + # # principle axes #scale=10.0 #c=cell.get_centre() @@ -158,40 +156,39 @@ def render_gl(self, selection=None): #glVertex2d(c[0],c[1]) #glVertex2d(c[0]+cell.pa2[0]*scale,c[1]+cell.pa2[1]*scale) #glEnd() - glDisable(GL_LIGHTING) - glDisable(GL_DEPTH_TEST) - cellStates = self.sim.cellStates + glDisable(GL_LIGHTING) + glDisable(GL_DEPTH_TEST) + cellStates = self.sim.cellStates - #for (cid,cellState) in cellStates.items(): - # cellcol = cellState.color - # glColor3fv(cellcol) + #for (cid,cellState) in cellStates.items(): + # cellcol = cellState.color + # glColor3fv(cellcol) # glBegin(GL_POLYGON) # for p in cellState.nodep: # glVertex2d(p[0], p[1]) # glEnd() - - for (cid,cellState) in cellStates.items(): - col = self.wallcol - for (wp1,wp2) in cellState.wallp: - glColor3fv(col) - glLineWidth(2) - glBegin(GL_LINES) - glVertex2d(wp1[0], wp1[1]) - glVertex2d(wp2[0], wp2[1]) - glEnd() - - if selection>0 and cellStates.has_key(selection): - scell = cellStates[selection] - glColor3fv([1,0,0]) - for (wp1,wp2) in scell.wallp: - glLineWidth(2) - glBegin(GL_LINES) - glVertex2d(wp1[0], wp1[1]) - glVertex2d(wp2[0], wp2[1]) - glEnd() - - # Draw nodes as points - #glColor3fv(self.nodecol) + for (cid,cellState) in cellStates.items(): + col = self.wallcol + for (wp1,wp2) in cellState.wallp: + glColor3fv(col) + glLineWidth(2) + glBegin(GL_LINES) + glVertex2d(wp1[0], wp1[1]) + glVertex2d(wp2[0], wp2[1]) + glEnd() + + if selection>0 and cellStates.has_key(selection): + scell = cellStates[selection] + glColor3fv([1,0,0]) + for (wp1,wp2) in scell.wallp: + glLineWidth(2) + glBegin(GL_LINES) + glVertex2d(wp1[0], wp1[1]) + glVertex2d(wp2[0], wp2[1]) + glEnd() + + # Draw nodes as points + #glColor3fv(self.nodecol) #glPointSize(3) #for node in self.model.nodes: @@ -211,280 +208,930 @@ def render_gl(self, selection=None): class GLBacteriumRenderer: - def __init__(self, sim, properties=None, scales = None): - self.ncells_list = 0 - self.ncells_names_list = 0 - self.names_list_step = -1 - self.list_step = -1 - self.dlist = None - self.dlist_names = None - self.cellcol = [1, 1, 1] - self.sim = sim - self.quad = gluNewQuadric() - self.properties = properties - self.scales = scales - - def init_gl(self): - pass - - def build_list(self, cells): - if self.dlist: - glDeleteLists(self.dlist, 1) - index = glGenLists(1) - glNewList(index, GL_COMPILE) - self.render_cells() - glEndList() - self.dlist = index - - def build_list_names(self, cells): - if self.dlist_names: - glDeleteLists(self.dlist_names, 1) - index = glGenLists(1) - glNewList(index, GL_COMPILE) - self.render_cell_names() - glEndList() - self.dlist_names = index - - def render_gl(self, selection=None): - # Uncomment this to directly draw all cells each frame - #self.render_cells() - - cells = self.sim.cellStates.values() - if self.sim.stepNum > self.list_step: - self.build_list(cells) - #self.ncells_list = len(cells) - self.list_step = self.sim.stepNum - - glCallList(self.dlist) - - if self.sim.cellStates.has_key(selection): - self.render_selected_cell(selection) - self.render_constraints() + def __init__(self, sim, properties=None, scales = None): + self.ncells_list = 0 + self.ncells_names_list = 0 + self.dlist = None + self.dlist_names = None + self.cellcol = [1, 1, 1] + self.sim = sim + self.quad = gluNewQuadric() + self.properties = properties + self.scales = scales + + def init_gl(self): + pass - def render_constraints(self): - phys = self.sim.phys - glDisable(GL_LIGHTING) - glEnable(GL_DEPTH_TEST) - glEnable(GL_LINE_SMOOTH) - glLineWidth(1.0) - #glBegin(GL_LINES) - glColor3f(1,0,0) - for i in range(phys.n_planes): - p = phys.plane_pts[i] - nn = phys.plane_norms[i] - n = [nn[i] for i in range(3)] - - # Make an orthonormal basis in the plane - v1 = numpy.cross([0,0,1],n) - if la.norm(v1)<1e-6: - v1 = numpy.cross([0,1,0],n) - v2 = numpy.cross(v1,n) - - glBegin(GL_LINE_STRIP) - glVertex3f(p[0], p[1], p[2]) - #glVertex3f(p[0]+n[0]*5, p[1]+n[1]*5, p[2]+n[2]*5) - glVertex3f(p[0]+v1[0]*5, p[1]+v1[1]*5, p[2]+v1[2]*5) - glVertex3f(p[0]+(v1[0]+v2[0])*5, p[1]+(v1[1]+v2[1])*5, p[2]+(v1[2]+v2[2])*5) - glVertex3f(p[0]+v2[0]*5, p[1]+v2[1]*5, p[2]+v2[2]*5) - glVertex3f(p[0], p[1], p[2]) - glEnd() - #glEnd() - glEnable(GL_LIGHTING) - glDisable(GL_DEPTH_TEST) - - - def render_selected_cell(self, selection): - glEnable(GL_DEPTH_TEST) - cellcol = [1,0,0] - cell = self.sim.cellStates[selection] - l = cell.length - r = cell.radius - - (e1,e2) = cell.ends - ae1 = numpy.array(e1) - ae2 = numpy.array(e2) - zaxis = numpy.array([0,0,1]) - caxis = numpy.array(cell.dir) #(ae2-ae1)/l - rotaxis = numpy.cross(caxis, zaxis) - rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) - - # draw the outlines antialiased in RED - glColor3f(1.0, 0.0, 0.0) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_LINE_SMOOTH) - glLineWidth(8.0) - # draw wireframe for back facing polygons and cull front-facing ones - glPolygonMode(GL_BACK, GL_FILL) - glEnable(GL_CULL_FACE) - glCullFace(GL_FRONT) - glDepthFunc(GL_LEQUAL) - - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1[0],e1[1],e1[2]) - gluSphere(self.quad, r, 8, 8) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2[0],e2[1],e2[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - glDisable(GL_DEPTH_TEST) - - - - def renderNames_gl(self, selection=None): - #self.render_cell_names() - cells = self.sim.cellStates.values() - if self.sim.stepNum > self.names_list_step: - self.build_list_names(cells) - self.names_list_step = self.sim.stepNum - glCallList(self.dlist_names) - - def render_cell_names(self): - glEnable(GL_DEPTH_TEST) - glDisable(GL_LIGHTING) - glDepthFunc(GL_LESS) - glDisable(GL_CULL_FACE) - glPolygonMode(GL_FRONT, GL_FILL) - glDisable(GL_LINE_SMOOTH) - glDisable(GL_BLEND) - - for cell in self.sim.cellStates.values(): - l = cell.length - r = cell.radius - - (e1,e2) = cell.ends - ae1 = numpy.array(e1) - ae2 = numpy.array(e2) - zaxis = numpy.array([0,0,1]) - caxis = numpy.array(cell.dir) #(ae2-ae1)/l - rotaxis = numpy.cross(caxis, zaxis) - rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) - - cid = cell.id - glPushName(cid) + #def render_text(self, position, textString, fontSize): + # pygame.font.init() + # font = pygame.font.Font (None, fontSize) + # textSurface = font.render(textString, True, (0,0,0,225), (255,255,255,255)) + # textData = pygame.image.tostring(textSurface, "RGBA", True) + # glRasterPos3d(*position) + # glDrawPixels(textSurface.get_width(), textSurface.get_height(), GL_RGBA, GL_UNSIGNED_BYTE, textData) + + def build_list(self, cells): + if self.dlist: + glDeleteLists(self.dlist, 1) + index = glGenLists(1) + glNewList(index, GL_COMPILE) + self.render_cells() + glEndList() + self.dlist = index + + def build_list_names(self, cells): + if self.dlist_names: + glDeleteLists(self.dlist_names, 1) + index = glGenLists(1) + glNewList(index, GL_COMPILE) + self.render_cell_names() + glEndList() + self.dlist_names = index + + def render_gl(self, selection=None): + cells = self.sim.cellStates.values() + states = self.sim.cellStates.items() + # FIXED ============================================================================= + # Before, the renderer would only draw cells when the number of cells changed. + # Now it draws them whenever render_gl is called (by paintGL in PyGLCMViewer.py) + self.build_list(cells) + self.ncells_list = len(cells) + + #if len(cells)!=self.ncells_list: + # self.build_list(cells) + # self.ncells_list = len(cells) + #==================================================================================== + glCallList(self.dlist) + #for cell in cells: self.render_cell(cell, selection) + + + def renderNames_gl(self, selection=None): + cells = self.sim.cellStates.values() + if len(cells)!=self.ncells_names_list: + self.build_list_names(cells) + self.ncells_names_list = len(cells) + glCallList(self.dlist_names) + #for cell in cells: self.render_cell_name(cell, selection) + + + def render_cell_names(self): + # glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + for cell in self.sim.cellStates.values(): + l = cell.length + r = cell.radius + + (e1,e2) = cell.ends + ae1 = numpy.array(e1) + ae2 = numpy.array(e2) + zaxis = numpy.array([0,0,1]) + caxis = numpy.array(cell.dir) #(ae2-ae1)/l + rotaxis = numpy.cross(caxis, zaxis) + rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) + + cid = cell.id + glPushName(cid) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1[0],e1[1],e1[2]) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - glPushMatrix() - glTranslatef(e2[0],e2[1],e2[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - glPopName() + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() - glEnable(GL_LIGHTING) - glDisable(GL_DEPTH_TEST) + glPopName() + glEnable(GL_LIGHTING) - def render_cells(self, selection=None): - glEnable(GL_DEPTH_TEST) - glDisable(GL_LIGHTING) - cells = self.sim.cellStates.values() - for cell in cells: - l = cell.length - #r = cell.radius*2.0 - r = cell.radius - - (e1,e2) = cell.ends - ae1 = numpy.array(e1) - ae2 = numpy.array(e2) - zaxis = numpy.array([0,0,1]) - caxis = numpy.array(cell.dir) #(ae2-ae1)/l - rotaxis = numpy.cross(caxis, zaxis) - rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) - - cid = cell.id - cellcol = cell.color #self.cellcol #[random.uniform(0,1), random.uniform(0,1), random.uniform(0,1)] - if self.properties: - cellcol = [] - for p in self.properties: - if hasattr(cell,p): - cellcol.append(getattr(cell,p)) - else: - cellcol.append(0) - for i in range(3): - cellcol[i] *= self.scales[i] - cellcol[i] = min(1,cellcol[i]) - - - # draw the outlines antialiased in black - glColor3f(0.0, 0.0, 0.0) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_LINE_SMOOTH) - glLineWidth(8.0) - # draw wireframe for back facing polygons and cull front-facing ones - glPolygonMode(GL_BACK, GL_FILL) - glEnable(GL_CULL_FACE) - glCullFace(GL_FRONT) - glDepthFunc(GL_LEQUAL) - - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1[0],e1[1],e1[2]) - gluSphere(self.quad, r, 8, 8) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2[0],e2[1],e2[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - glDepthFunc(GL_LESS) - glDisable(GL_CULL_FACE) - glPolygonMode(GL_FRONT, GL_FILL) - glDisable(GL_LINE_SMOOTH) - glDisable(GL_BLEND) - - glColor3fv(cellcol) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1[0],e1[1],e1[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - #glScalef(1.25,1.0,1.0) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l*1.25, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2[0],e2[1],e2[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() + def render_cells(self, selection=None): + + # PLACEHOLDER + + #glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + cells = self.sim.cellStates.values() + for cell in cells: + l = cell.length + #r = cell.radius*2.0 + r = cell.radius + + (e1,e2) = cell.ends + ae1 = numpy.array(e1) + ae2 = numpy.array(e2) + zaxis = numpy.array([0,0,1]) + caxis = numpy.array(cell.dir) #(ae2-ae1)/l + rotaxis = numpy.cross(caxis, zaxis) + rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) + + cid = cell.id + cidx = cell.idx + if False: + self.render_text(0.5*(e1+e2), str(cidx), 24) + + if selection==cid: + cellcol = [1,0,0] + else: + cellcol = cell.color #self.cellcol #[random.uniform(0,1), random.uniform(0,1), random.uniform(0,1)] + if self.properties: + cellcol = [] + for p in self.properties: + if hasattr(cell,p): + cellcol.append(getattr(cell,p)) + else: + cellcol.append(0) + for i in range(3): + cellcol[i] *= self.scales[i] + cellcol[i] = min(1,cellcol[i]) + + # draw the outlines antialiased in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + #glColor3f(68.0 / 256, 81.0 / 256, 44.0 / 256) + #glLineWidth(2) + #glBegin(GL_LINES) + #glVertex3f(e1[0], e1[1], e1[2]) + #glVertex3f(e2[0], e2[1], e2[2]) + #glEnd() + # + #glColor3f(1.0, 1.0, 0.0) + #glPointSize(3) + #glBegin(GL_POINTS) + #glVertex3f(e1[0], e1[1], e1[2]) + #glVertex3f(e2[0], e2[1], e2[2]) + #glEnd() + + # draw contact points + if False: #hasattr(cells[0], 'contacts'): + glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + for cell in cells: + contacts = cell.contacts + glBegin(GL_LINES) + for ct in contacts: + glColor3fv(ct[6:9]) + glVertex3fv(ct[0:3]) + glVertex3fv(ct[3:6]) + glEnd() + glBegin(GL_POINTS) + for ct in contacts: + glColor3fv(ct[6:9]) + glVertex3fv(ct[0:3]) + glEnd() + glEnable(GL_DEPTH_TEST) + glEnable(GL_LIGHTING) + +class GLBacteriumRendererWithPeriodicImages: + def __init__(self, sim, properties=None, scales = None): + self.ncells_list = 0 + self.ncells_names_list = 0 + self.dlist = None + self.dlist_names = None + self.cellcol = [1, 1, 1] + self.sim = sim + self.quad = gluNewQuadric() + self.properties = properties + self.scales = scales + + def init_gl(self): + pass + + def build_list(self, cells): + if self.dlist: + glDeleteLists(self.dlist, 1) + index = glGenLists(1) + glNewList(index, GL_COMPILE) + self.render_cells() + textString = 'CellModeller4 Development Version' #self.render_text(position, textString, 40) + position = numpy.array([-40.0,30.0,0.0]) + glEndList() + self.dlist = index + + def build_list_names(self, cells): + if self.dlist_names: + glDeleteLists(self.dlist_names, 1) + index = glGenLists(1) + glNewList(index, GL_COMPILE) + self.render_cell_names() + glEndList() + self.dlist_names = index + + def render_gl(self, selection=None): + cells = self.sim.cellStates.values() + states = self.sim.cellStates.items() + # FIXED ============================================================================= + # Before, the renderer would only draw cells when the number of cells changed. + # Now it draws them whenever render_gl is called (by paintGL in PyGLCMViewer.py) + + names = False + if not names: + self.build_list(cells) + self.ncells_list = len(cells) + glCallList(self.dlist) + else: + # added to try and render cell ids + self.build_list_names(cells) + self.ncells_names_list = len(cells) + glCallList(self.dlist_names) + + #if len(cells)!=self.ncells_list: + # self.build_list(cells) + # self.ncells_list = len(cells) + #==================================================================================== + #glCallList(self.dlist) + #glCallList(self.dlist_names) + #for cell in cells: self.render_cell(cell, selection) + + + def renderNames_gl(self, selection=None): + cells = self.sim.cellStates.values() + if len(cells)!=self.ncells_names_list: + self.build_list_names(cells) + self.ncells_names_list = len(cells) + glCallList(self.dlist_names) + #for cell in cells: self.render_cell_name(cell, selection) + + + def render_cell_names(self): + # glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + for cell in self.sim.cellStates.values(): + l = cell.length + r = cell.radius + + (e1,e2) = cell.ends + ae1 = numpy.array(e1) + ae2 = numpy.array(e2) + zaxis = numpy.array([0,0,1]) + caxis = numpy.array(cell.dir) #(ae2-ae1)/l + rotaxis = numpy.cross(caxis, zaxis) + rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) + + cid = cell.id + glPushName(cid) + + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glPopName() + + glEnable(GL_LIGHTING) + + #def render_text(self, position, textString, fontSize): + # pygame.font.init() + # font = pygame.font.Font (None, fontSize) + # textSurface = font.render(textString, True, (0,0,0,225), (255,255,255,255)) + # textData = pygame.image.tostring(textSurface, "RGBA", True) + # glRasterPos3d(*position) + # glDrawPixels(textSurface.get_width(), textSurface.get_height(), GL_RGBA, GL_UNSIGNED_BYTE, textData) + # #glClear(GL_DEPTH_BUFFER_BIT) + + def render_cells(self, selection=None): + #glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + cells = self.sim.cellStates.values() + for cell in cells: + l = cell.length + #r = cell.radius*2.0 + r = cell.radius + + (e1,e2) = cell.ends + + L_x = self.sim.phys.max_x_coord - self.sim.phys.min_x_coord + L_y = self.sim.phys.max_y_coord - self.sim.phys.min_y_coord + offset_x = numpy.array([L_x,0.0,0.0]) + offset_y = numpy.array([0.0,L_y,0.0]) + + # top image + e1_t = e1 + offset_y + e2_t = e2 + offset_y + # bottom image + e1_b = e1 - offset_y + e2_b = e2 - offset_y + # left image + e1_l = e1 - offset_x + e2_l = e2 - offset_x + # right image + e1_r = e1 + offset_x + e2_r = e2 + offset_x + + zaxis = numpy.array([0,0,1]) + caxis = numpy.array(cell.dir) #(ae2-ae1)/l + rotaxis = numpy.cross(caxis, zaxis) + rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) + + cid = cell.id + #======================================================== Adding cell labels + cidx = cell.idx + #if self.sim.render_labels: + if False: + self.render_text(0.5*(e1+e2), str(cidx), 24) + #======================================================== + if selection==cid: + cellcol = [1,0,0] + else: + cellcol = cell.color #self.cellcol #[random.uniform(0,1), random.uniform(0,1), random.uniform(0,1)] + if self.properties: + cellcol = [] + for p in self.properties: + if hasattr(cell,p): + cellcol.append(getattr(cell,p)) + else: + cellcol.append(0) + for i in range(3): + cellcol[i] *= self.scales[i] + cellcol[i] = min(1,cellcol[i]) + + # image cells are grey + cellcol2 = numpy.array([0.9,0.9,0.9]) + + # main image + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + # FIXME ========================================= + #() + #================================================ + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + # draw contact points + #========================================================= + if hasattr(cells[0], 'contacts'): + #========================================================= used to always be false but it won't work anyway - see below + glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + for cell in cells: + contacts = cell.contacts # this won't work because cellStates no longer have a contacts attribute + glBegin(GL_LINES) + for ct in contacts: + glColor3fv(ct[6:9]) + glVertex3fv(ct[0:3]) + glVertex3fv(ct[3:6]) + glEnd() + glBegin(GL_POINTS) + for ct in contacts: + glColor3fv(ct[6:9]) + glVertex3fv(ct[0:3]) + glEnd() + glEnable(GL_DEPTH_TEST) + glEnable(GL_LIGHTING) + + # top image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_t[0],e1_t[1],e1_t[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_t[0],e2_t[1],e2_t[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_t[0],e1_t[1],e1_t[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_t[0],e2_t[1],e2_t[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + + # bottom image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_b[0],e1_b[1],e1_b[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_b[0],e2_b[1],e2_b[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_b[0],e1_b[1],e1_b[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_b[0],e2_b[1],e2_b[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + + # left image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_l[0],e1_l[1],e1_l[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_l[0],e2_l[1],e2_l[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_l[0],e1_l[1],e1_l[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_l[0],e2_l[1],e2_l[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + # right image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_r[0],e1_r[1],e1_r[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_r[0],e2_r[1],e2_r[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_r[0],e1_r[1],e1_r[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_r[0],e2_r[1],e2_r[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + if True: + # prepare diagonal images + # top right image + e1_tr = e1 + offset_y + offset_x + e2_tr = e2 + offset_y + offset_x + # bottom right image + e1_br = e1 - offset_y + offset_x + e2_br = e2 - offset_y + offset_x + # top left image + e1_tl = e1 - offset_x + offset_y + e2_tl = e2 - offset_x + offset_y + # bottom left image + e1_bl = e1 - offset_x - offset_y + e2_bl = e2 - offset_x - offset_y + # top-right image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_tr[0],e1_tr[1],e1_tr[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_tr[0],e2_tr[1],e2_tr[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_tr[0],e1_tr[1],e1_tr[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_tr[0],e2_tr[1],e2_tr[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + + # bottom right image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_br[0],e1_br[1],e1_br[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_br[0],e2_br[1],e2_br[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_br[0],e1_br[1],e1_br[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_br[0],e2_br[1],e2_br[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ - # draw contact points - if False: #hasattr(cells[0], 'contacts'): - glDisable(GL_DEPTH_TEST) - glDisable(GL_LIGHTING) - for cell in cells: - contacts = cell.contacts - glBegin(GL_LINES) - for ct in contacts: - glColor3fv(ct[6:9]) - glVertex3fv(ct[0:3]) - glVertex3fv(ct[3:6]) - glEnd() - glBegin(GL_POINTS) - for ct in contacts: - glColor3fv(ct[6:9]) - glVertex3fv(ct[0:3]) - glEnd() - glEnable(GL_DEPTH_TEST) - glEnable(GL_LIGHTING) + # top left image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_tl[0],e1_tl[1],e1_tl[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_tl[0],e2_tl[1],e2_tl[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_tl[0],e1_tl[1],e1_tl[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_tl[0],e2_tl[1],e2_tl[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + # bottom left image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_bl[0],e1_bl[1],e1_bl[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_bl[0],e2_bl[1],e2_bl[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_bl[0],e1_bl[1],e1_bl[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_bl[0],e2_bl[1],e2_bl[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + #glColor3f(68.0 / 256, 81.0 / 256, 44.0 / 256) + #glLineWidth(2) + #glBegin(GL_LINES) + #glVertex3f(e1[0], e1[1], e1[2]) + #glVertex3f(e2[0], e2[1], e2[2]) + #glEnd() + # + #glColor3f(1.0, 1.0, 0.0) + #glPointSize(3) + #glBegin(GL_POINTS) + #glVertex3f(e1[0], e1[1], e1[2]) + #glVertex3f(e2[0], e2[1], e2[2]) + #glEnd() + + +class GLWillsMeshRenderer: + def __init__(self,sim): + self.sim = sim + + def render_gl(self, selection=None): # is it necessary to have this method? YES + self.render_mesh() + + def render_mesh(self): - + # choose mesh color + glColor3f(0,1,0) # green + + # get domain info + min_x = self.sim.phys.min_x_coord + min_y = self.sim.phys.min_y_coord + max_x = self.sim.phys.max_x_coord + max_y = self.sim.phys.max_y_coord + nx = self.sim.phys.grid_x_max - self.sim.phys.grid_x_min + ny = self.sim.phys.grid_y_max - self.sim.phys.grid_y_min + z_offset = -0.1 + h = self.sim.phys.grid_spacing + glLineWidth(2) + + # render lines in x direction + for i in range(0,ny+1): + glBegin( GL_LINES ) + glVertex3f(min_x, min_y + i*h, z_offset) + glVertex3f(max_x, min_y + i*h, z_offset) + glEnd( ) + + # render lines in y direction + for j in range(0,nx+1): + glBegin( GL_LINES ) + glVertex3f(min_x + j*h, min_y, z_offset) + glVertex3f(min_x + j*h, max_y, z_offset) + glEnd( ) + + + + class GLStaticMeshRenderer: def __init__(self, mesh, regul): self.mesh = mesh @@ -558,8 +1205,8 @@ def render_gl(self, selection=None): cid = c.getId() if selection!=cid: s = states[cid] - if len(s.signals)>0: - glColor4f(s.signals[0],0,0,1) + if len(s.signals)>0: + glColor4f(s.signals[0],0,0,1) else: glColor4fv(c.color) #c.color[0:3]) else: @@ -786,7 +1433,7 @@ def render_cell_name(self, cell): def render_gl(self, selection=None): - cells = self.sim.cellStates.values() + cells = self.sim.cellStates.values() for cell in cells: self.render_cell(cell, selection) def renderNames_gl(self, selection=None): @@ -895,9 +1542,9 @@ def render_gl(self, selection=None): glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) cells = self.sim.cellStates.values() - if len(cells)!=self.ncells_list: - self.build_list(cells) - self.ncells_list = len(cells) + #if len(cells)!=self.ncells_list: + self.build_list(cells) + #self.ncells_list = len(cells) glCallList(self.dlist) #for cell in cells: self.render_cell(cell, selection) diff --git a/CellModeller/Integration/CLCrankNicIntegrator.py b/CellModeller/Integration/CLCrankNicIntegrator.py index 3b673aa8..39ee8655 100644 --- a/CellModeller/Integration/CLCrankNicIntegrator.py +++ b/CellModeller/Integration/CLCrankNicIntegrator.py @@ -7,6 +7,7 @@ import pyopencl.array as cl_array from pyopencl.array import vec import math +from functools import reduce def unique_stable(ar, return_index=False, return_inverse=False): @@ -102,7 +103,7 @@ def __init__(self, sim, nSignals, nSpecies, maxCells, sig, greensThreshold=1e-12 # set the species for existing states to views of the levels array cs = self.cellStates - for id,c in cs.items(): + for id,c in list(cs.items()): c.species = self.specLevel[c.idx,:] @@ -135,7 +136,7 @@ def computeGreensFunc(self): self.greensFunc = self.greensFunc[:, min(inds[:,1]):max(inds[:,1])+1, \ min(inds[:,2]):max(inds[:,2])+1, \ min(inds[:,3]):max(inds[:,3])+1] - print "Truncated Green's function size is " + str(self.greensFunc.shape) + print("Truncated Green's function size is " + str(self.greensFunc.shape)) def addCell(self, cellState): @@ -203,7 +204,7 @@ def initKernels(self): sigRateKernel = self.regul.sigRateCL() #kernel_src = open('CellModeller/Integration/CLCrankNicIntegrator.cl', 'r').read() from pkg_resources import resource_string - kernel_src = resource_string(__name__, 'CLCrankNicIntegrator.cl') + kernel_src = resource_string(__name__, 'CLCrankNicIntegrator.cl').decode() # substitute user defined kernel code, and number of signals kernel_src = kernel_src % {'sigKernel': sigRateKernel, 'specKernel': specRateKernel, @@ -292,7 +293,7 @@ def dydt(self): def step(self, dt): if dt!=self.dt: - print "I can only integrate at fixed dt!" + print("I can only integrate at fixed dt!") return self.nCells = len(self.cellStates) @@ -301,9 +302,9 @@ def step(self, dt): s = self.specLevel[self.nCells-1] except IndexError: # Could resize here, then would have to rebuild views - print "Number of cells exceeded " \ + print("Number of cells exceeded " \ + self.__class__.__name__ \ - + "::maxCells (" + self.maxCells + ")" + + "::maxCells (" + self.maxCells + ")") self.dataLen = self.signalDataLen + self.nCells*self.nSpecies @@ -343,7 +344,7 @@ def step(self, dt): # c.signals = self.signalling.signals(c, self.signalLevel) # Update cellType array - for (id,c) in self.cellStates.items(): + for (id,c) in list(self.cellStates.items()): self.celltype[c.idx] = numpy.int32(c.cellType) self.celltype_dev.set(self.celltype) @@ -366,7 +367,7 @@ def setLevels(self, SSLevel, cellSigData): self.specLevel_dev.set(self.specLevel) self.cellSigLevels_dev.set(self.cellSigLevels) cs = self.cellStates - for id,c in cs.items(): #make sure everything is correct here + for id,c in list(cs.items()): #make sure everything is correct here c.species = self.specLevel[c.idx,:] c.signals = self.cellSigLevels[c.idx,:] self.celltype[c.idx] = numpy.int32(c.cellType) diff --git a/CellModeller/Integration/CLEulerIntegrator.py b/CellModeller/Integration/CLEulerIntegrator.py index 9b630d2b..3db4d153 100644 --- a/CellModeller/Integration/CLEulerIntegrator.py +++ b/CellModeller/Integration/CLEulerIntegrator.py @@ -36,7 +36,7 @@ def __init__(self, sim, nSpecies, maxCells, regul=None): # set the species for existing states to views of the levels array cs = self.cellStates - for id,c in cs.items(): + for id,c in list(cs.items()): c.species = self.specLevel[c.idx,:] @@ -95,8 +95,7 @@ def initKernels(self): # Get user defined kernel source specRateKernel = self.regul.specRateCL() from pkg_resources import resource_string - kernel_src = resource_string(__name__, 'CLEulerIntegrator.cl') - #kernel_src = open('CellModeller/Integration/CLEulerIntegrator.cl', 'r').read() + kernel_src = resource_string(__name__, 'CLEulerIntegrator.cl').decode() # substitute user defined kernel code, and number of signals kernel_src = kernel_src%(specRateKernel) self.program = cl.Program(self.context, kernel_src).build(cache_dir=False) @@ -119,7 +118,7 @@ def dydt(self): def step(self, dt): if dt!=self.dt: - print "I can only integrate at fixed dt!" + print("I can only integrate at fixed dt!") return self.nCells = len(self.cellStates) @@ -128,15 +127,15 @@ def step(self, dt): s = self.specLevel[self.nCells-1] except IndexError: # Could resize here, then would have to rebuild views - print "Number of cells exceeded " \ + print("Number of cells exceeded " \ + self.__class__.__name__ \ - + "::maxCells (" + self.maxCells + ")" + + "::maxCells (" + self.maxCells + ")") self.dataLen = self.nCells*self.nSpecies self.cellStates = self.sim.cellStates cs = self.cellStates - for id,c in cs.items(): + for id,c in list(cs.items()): self.effgrow[c.idx] = numpy.float32(c.effGrowth) self.effgrow_dev.set(self.effgrow) @@ -160,7 +159,7 @@ def setLevels(self, specLevel): self.makeViews() self.specLevel_dev.set(self.specLevel) cs = self.cellStates - for id,c in cs.items(): + for id,c in list(cs.items()): c.species = self.specLevel[c.idx,:] self.celltype[c.idx] = numpy.int32(c.cellType) self.celltype_dev.set(self.celltype) diff --git a/CellModeller/Integration/CLEulerSigIntegrator.py b/CellModeller/Integration/CLEulerSigIntegrator.py index 8986e388..7e75b062 100644 --- a/CellModeller/Integration/CLEulerSigIntegrator.py +++ b/CellModeller/Integration/CLEulerSigIntegrator.py @@ -7,6 +7,7 @@ import pyopencl.array as cl_array from pyopencl.array import vec import math +from functools import reduce def unique_stable(ar, return_index=False, return_inverse=False): @@ -100,7 +101,7 @@ def __init__(self, sim, nSignals, nSpecies, maxCells, sig, regul=None, boundcond # set the species for existing states to views of the levels array cs = self.cellStates - for id,c in cs.items(): + for id,c in list(cs.items()): c.species = self.specLevel[c.idx,:] @@ -177,7 +178,7 @@ def initKernels(self): sigRateKernel = self.regul.sigRateCL() #kernel_src = open('CellModeller/Integration/CLCrankNicIntegrator.cl', 'r').read() from pkg_resources import resource_string - kernel_src = resource_string(__name__, 'CLCrankNicIntegrator.cl') + kernel_src = resource_string(__name__, 'CLCrankNicIntegrator.cl').decode() # substitute user defined kernel code, and number of signals kernel_src = kernel_src % {'sigKernel': sigRateKernel, 'specKernel': specRateKernel, @@ -266,7 +267,7 @@ def dydt(self): def step(self, dt): if dt!=self.dt: - print "I can only integrate at fixed dt!" + print("I can only integrate at fixed dt!") return self.nCells = len(self.cellStates) @@ -275,9 +276,9 @@ def step(self, dt): s = self.specLevel[self.nCells-1] except IndexError: # Could resize here, then would have to rebuild views - print "Number of cells exceeded " \ + print("Number of cells exceeded " \ + self.__class__.__name__ \ - + "::maxCells (" + self.maxCells + ")" + + "::maxCells (" + self.maxCells + ")") self.dataLen = self.signalDataLen + self.nCells*self.nSpecies @@ -312,7 +313,7 @@ def step(self, dt): # c.signals = self.signalling.signals(c, self.signalLevel) # Update cellType array - for (id,c) in self.cellStates.items(): + for (id,c) in list(self.cellStates.items()): self.celltype[c.idx] = numpy.int32(c.cellType) self.celltype_dev.set(self.celltype) @@ -335,7 +336,7 @@ def setLevels(self, SSLevel, cellSigData): self.specLevel_dev.set(self.specLevel) self.cellSigLevels_dev.set(self.cellSigLevels) cs = self.cellStates - for id,c in cs.items(): #make sure everything is correct here + for id,c in list(cs.items()): #make sure everything is correct here c.species = self.specLevel[c.idx,:] c.signals = self.cellSigLevels[c.idx,:] self.celltype[c.idx] = numpy.int32(c.cellType) diff --git a/CellModeller/Regulation/ModuleRegulator.py b/CellModeller/Regulation/ModuleRegulator.py index 009ec390..4ef2bf1c 100644 --- a/CellModeller/Regulation/ModuleRegulator.py +++ b/CellModeller/Regulation/ModuleRegulator.py @@ -40,7 +40,7 @@ def speciesRates(self, cstate, speciesLevels, signalLevels): return self.module.speciesRates(cstate, speciesLevels, signalLevels) def initSpeciesLevels(self, levels): - csv = self.cellStates.values() + csv = list(self.cellStates.values()) nCells = len(csv) for i in range(nCells): levels[i,:] = csv[i].species @@ -49,8 +49,8 @@ def step(self, dt=0): try: self.module.update(self.cellStates) except Exception as e: - print "Problem with regulation module " + self.modName - print e + print("Problem with regulation module " + self.modName) + print(e) def divide(self, pState, d1State, d2State): # Call the module's optional divide function diff --git a/CellModeller/Regulation/SBMLImport.py b/CellModeller/Regulation/SBMLImport.py index 4d7d230a..6bdcb3e6 100644 --- a/CellModeller/Regulation/SBMLImport.py +++ b/CellModeller/Regulation/SBMLImport.py @@ -1,7 +1,7 @@ from libsbml import * import math import new -import urllib2 +import urllib.request, urllib.error, urllib.parse # indicates whether we should perform SBML document consistency check. @@ -11,8 +11,8 @@ # get the array index of given species ID: def getSpecIndex(specIdToArrayIndexDict, specId): - if not specIdToArrayIndexDict.has_key(specId): - specIdToArrayIndexDict[specId] = len(specIdToArrayIndexDict.keys()) + if specId not in specIdToArrayIndexDict: + specIdToArrayIndexDict[specId] = len(list(specIdToArrayIndexDict.keys())) return specIdToArrayIndexDict[specId] @@ -31,7 +31,7 @@ def checkSBMLConsistency(document): if numFailures > 0: failureMsg = "" for failureNum in range(numFailures): - print "Failure " + str(failureNum) + ": " + document.getError(failureNum).getShortMessage() + "\n" + print("Failure " + str(failureNum) + ": " + document.getError(failureNum).getShortMessage() + "\n") raise Exception(failureMsg) @@ -40,11 +40,11 @@ def SBMLModelFromSBMLFile(sbmlFile): reader = SBMLReader() document = reader.readSBML(sbmlFile) if document.getNumErrors()>0: - print "Errors in reading SBML file..." + print("Errors in reading SBML file...") checkSBMLConsistency(document) model = document.getModel() if not model: - print "No model!" + print("No model!") return model @@ -120,7 +120,7 @@ def pythonMathFromASTNode(astNode, kineticLaw, model): # something weird -- return 1 and issue warning: else: - print "WARNING: unknown identifier " + nodeName + ", defaulting to 1. Globals: " + str(model.getNumParameters()) + ". Locals: " + str(kineticLaw.getNumParameters()) + print("WARNING: unknown identifier " + nodeName + ", defaulting to 1. Globals: " + str(model.getNumParameters()) + ". Locals: " + str(kineticLaw.getNumParameters())) return "1" else: @@ -184,7 +184,7 @@ def pythonStrFromSBMLModel(model): reactantSpecId = reactantSpecRef.getSpecies() # add key to hash table if it doesn't exist: - if not specIdToExpDict.has_key(reactantSpecId): + if reactantSpecId not in specIdToExpDict: specIdToExpDict[reactantSpecId] = "" if stoich == 1: @@ -204,7 +204,7 @@ def pythonStrFromSBMLModel(model): productSpecId = productSpecRef.getSpecies() # add key to hash table if it doesn't exist: - if not specIdToExpDict.has_key(productSpecId): + if productSpecId not in specIdToExpDict: specIdToExpDict[productSpecId] = "" if stoich == 1: @@ -217,7 +217,7 @@ def pythonStrFromSBMLModel(model): pythonVarDefs = "" pythonRateUpdateExps = "" specIdLst = [0]*len(specIdToExpDict) - for specId in specIdToExpDict.keys(): + for specId in list(specIdToExpDict.keys()): # get index into species array: index = getSpecIndex(specIdToArrayIndexDict, specId) @@ -302,13 +302,13 @@ def pythonStrFromSBMLModel(model): # create python module from code dynamically. def pythonModuleFromPythonStr(pythonStr): module = new.module("sbmlPythonEncoding") - exec pythonStr in module.__dict__ + exec(pythonStr, module.__dict__) return module # get text from given channel. def TextFromChannel(channelName): - f = urllib2.urlopen('http://async-message-passer.appspot.com/?content_only=1&channel_name=' + channelName) + f = urllib.request.urlopen('http://async-message-passer.appspot.com/?content_only=1&channel_name=' + channelName) return f.read() @@ -318,7 +318,7 @@ def pythonModuleFromFile(fileName): checkSBMLConsistency(document) model = document.getModel() pstr = pythonStrFromSBMLModel(model) - print "Got python str: " + pstr + print("Got python str: " + pstr) pythonModule = pythonModuleFromPythonStr(pstr) return pythonModule @@ -344,7 +344,7 @@ def pythonModuleFromChannel(channelName): pythonStr = pythonStrFromSBMLModel(model) - print "Got python str: " + pythonStr + print("Got python str: " + pythonStr) pythonModule = pythonModuleFromPythonStr(pythonStr) return pythonModule diff --git a/CellModeller/Signalling/GridDiffusion.py b/CellModeller/Signalling/GridDiffusion.py index f8292dd2..8689ee40 100644 --- a/CellModeller/Signalling/GridDiffusion.py +++ b/CellModeller/Signalling/GridDiffusion.py @@ -2,6 +2,7 @@ import numpy from scipy.ndimage import laplace from scipy.ndimage.filters import convolve +from functools import reduce class GridDiffusion: @@ -49,8 +50,8 @@ def setRegulator(self, regul): self.regul = regul def flattenIdx(self, idx): - print "idx = " + str(idx) - print "flat idx = " + str(idx[2] + idx[1]*self.gridDim[3] + idx[0]*self.gridDim[2]*self.gridDim[3]) + print("idx = " + str(idx)) + print("flat idx = " + str(idx[2] + idx[1]*self.gridDim[3] + idx[0]*self.gridDim[2]*self.gridDim[3])) return idx[2] + idx[1]*self.gridDim[3] + idx[0]*self.gridDim[2]*self.gridDim[3] def idxFromPos(self, p): @@ -76,7 +77,7 @@ def trilinearWeights(self, p): w[1,0,1] = dx*(1-dy)*dz if x>=-1 and x=0 and y=-1 and z=0 and x=-1 and y=-1 and z=-1 and x=-1 and y=-1 and zidmax: @@ -273,7 +273,7 @@ def reset(self): if not self.moduleStr: #This will take up any changes made in the model file - reload(self.module) + importlib.reload(self.module) else: # TJR: Module loaded from pickle, cannot reset? pass @@ -349,7 +349,7 @@ def addCell(self, cellType=0, cellAdh=0, length=3.5, **kwargs): # Eventually prob better to have a generic editCell() that deals with this stuff # def moveCell(self, cid, delta_pos): - if self.cellStates.has_key(cid): + if cid in self.cellStates: self.phys.moveCell(self.cellStates[cid], delta_pos) ## Proceed to the next simulation step @@ -357,7 +357,7 @@ def moveCell(self, cid, delta_pos): def step(self): self.reg.step(self.dt) states = dict(self.cellStates) - for (cid,state) in states.items(): + for (cid,state) in list(states.items()): if state.divideFlag: self.divide(state) #neighbours no longer current @@ -408,7 +408,7 @@ def writePickle(self, csv=False): if self.sig: data['sigData'] = self.integ.cellSigLevels data['sigGrid'] = self.integ.signalLevel - cPickle.dump(data, outfile, protocol=-1) + pickle.dump(data, outfile, protocol=-1) #output csv file with cell pos,dir,len - sig? # Populate simulation from saved data pickle @@ -419,7 +419,7 @@ def loadFromPickle(self, data): idx_map = {} id_map = {} idmax = 0 - for id,state in data['cellStates'].iteritems(): + for id,state in data['cellStates'].items(): idx_map[state.id] = state.idx id_map[state.idx] = state.id if id>idmax: @@ -429,9 +429,9 @@ def loadFromPickle(self, data): self._next_id = idmax+1 self._next_idx = len(data['cellStates']) if self.integ: - if data.has_key('sigData'): + if 'sigData' in data: self.integ.setLevels(data['specData'],data['sigData']) - elif data.has_key('specData'): + elif 'specData' in data: self.integ.setLevels(data['specData']) diff --git a/Examples/ACS2012/EdgeDetectorChamber.py b/Examples/ACS2012/EdgeDetectorChamber.py index 63048088..e8698d97 100644 --- a/Examples/ACS2012/EdgeDetectorChamber.py +++ b/Examples/ACS2012/EdgeDetectorChamber.py @@ -91,9 +91,9 @@ def sigRateCL(): def update(cells): if len(cells) > max_cells-16: - print 'reached cell limit' + print('reached cell limit') exit() - for (i,cell) in cells.iteritems(): + for (i,cell) in cells.items(): cell.color = [0.1, 0.1+cell.species[3]/10.0, 0.1+cell.species[4]*20.0] if cell.volume > getattr(cell, 'target_volume', 3.0): cell.divideFlag = True diff --git a/Examples/Conjugation.py b/Examples/Conjugation.py index a2896e42..0060acd1 100644 --- a/Examples/Conjugation.py +++ b/Examples/Conjugation.py @@ -40,7 +40,7 @@ def init(cell): def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/TimRudgeThesis/Meristem.py b/Examples/TimRudgeThesis/Meristem.py index a35645f5..6b116468 100644 --- a/Examples/TimRudgeThesis/Meristem.py +++ b/Examples/TimRudgeThesis/Meristem.py @@ -33,7 +33,7 @@ def init(cell): def max_x_coord(cells): mx = -1000 - for i,cell in cells.items(): + for i,cell in list(cells.items()): mx = max(mx, cell.pos[0]) return mx @@ -43,7 +43,7 @@ def update(cells): global growth_rad rightmost = -1 edge = max_x_coord(cells) - for (i,cell) in cells.items(): + for (i,cell) in list(cells.items()): dist = edge - cell.pos[0] if dist < growth_rad: cell.growthRate = 0.5 #(growth_rad-dist)/growth_rad * 0.5 diff --git a/Examples/Tutorial_1/Tutorial_1a.py b/Examples/Tutorial_1/Tutorial_1a.py index ecb2d2cd..081282b2 100644 --- a/Examples/Tutorial_1/Tutorial_1a.py +++ b/Examples/Tutorial_1/Tutorial_1a.py @@ -33,7 +33,7 @@ def init(cell): def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/Tutorial_1/Tutorial_1b.py b/Examples/Tutorial_1/Tutorial_1b.py index af3118ca..5f529c9d 100644 --- a/Examples/Tutorial_1/Tutorial_1b.py +++ b/Examples/Tutorial_1/Tutorial_1b.py @@ -32,7 +32,7 @@ def setup(sim): def max_y_coord(cells): #finds the largest y-coordinate in the colony my = 0.0 - for i,cell in cells.items(): + for i,cell in list(cells.items()): my = max(my, cell.pos[1]) return my @@ -46,7 +46,7 @@ def init(cell): def update(cells): #Iterate through each cell and flag cells that reach target size for division maxy = max_y_coord(cells) - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): dist = maxy - cell.pos[1] growthZone = 5.0 #width of the growth zone if dist < growthZone: diff --git a/Examples/Tutorial_1/Tutorial_1c.py b/Examples/Tutorial_1/Tutorial_1c.py index 26569e97..1eb30636 100644 --- a/Examples/Tutorial_1/Tutorial_1c.py +++ b/Examples/Tutorial_1/Tutorial_1c.py @@ -37,7 +37,7 @@ def init(cell): def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/Tutorial_2/Tutorial_2a.py b/Examples/Tutorial_2/Tutorial_2a.py index b92da170..8855a2f4 100644 --- a/Examples/Tutorial_2/Tutorial_2a.py +++ b/Examples/Tutorial_2/Tutorial_2a.py @@ -52,7 +52,7 @@ def specRateCL(): def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [numpy.clip(cell.species[0]/6.0,0.0,1.0), 1.0, 0.1] if cell.volume > cell.targetVol: a = 1 diff --git a/Examples/Tutorial_2/Tutorial_2b.py b/Examples/Tutorial_2/Tutorial_2b.py index 2eeadd21..b584e5f1 100644 --- a/Examples/Tutorial_2/Tutorial_2b.py +++ b/Examples/Tutorial_2/Tutorial_2b.py @@ -57,7 +57,7 @@ def specRateCL(): def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [numpy.clip((cell.species[0]-0.53)/0.05,0.0,1.0), 0.1, 0.1] if cell.volume > cell.targetVol: a = 1 diff --git a/Examples/Tutorial_3/Tutorial_3.py b/Examples/Tutorial_3/Tutorial_3.py index d724f996..61e13795 100644 --- a/Examples/Tutorial_3/Tutorial_3.py +++ b/Examples/Tutorial_3/Tutorial_3.py @@ -98,7 +98,7 @@ def update(cells): #Iterate through each cell and flag cells that reach target size for division v_max = 0.9 Km = 0.1 #This can be though of as the degree of mutualism - turns mutualism off when set to 0. - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [1,1,1] #[0.1+cell.species[0]/3.0, 0.1+cell.species[1]/3.0, 0.1] if cell.cellType==0: cell.growthRate = 0.1 + v_max * cell.species[1] / (Km + cell.species[1]) diff --git a/Examples/colorWalk_planes_3d.py b/Examples/colorWalk_planes_3d.py index dfb84911..358c934e 100644 --- a/Examples/colorWalk_planes_3d.py +++ b/Examples/colorWalk_planes_3d.py @@ -57,7 +57,7 @@ def numSpecies(): return 0 def update(cells): - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/ex1_simpleGrowth.py b/Examples/ex1_simpleGrowth.py index 9bc8cb28..6be5c195 100644 --- a/Examples/ex1_simpleGrowth.py +++ b/Examples/ex1_simpleGrowth.py @@ -25,7 +25,7 @@ def setup(sim): therenderer = Renderers.GLBacteriumRenderer(sim) sim.addRenderer(therenderer) else: - print "Running in batch mode: no display will be output" + print("Running in batch mode: no display will be output") sim.pickleSteps = 10 sim.saveOutput = True @@ -39,7 +39,7 @@ def init(cell): def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/ex1_simpleGrowth2D.py b/Examples/ex1_simpleGrowth2D.py index 251c9ea3..406b63a2 100644 --- a/Examples/ex1_simpleGrowth2D.py +++ b/Examples/ex1_simpleGrowth2D.py @@ -33,7 +33,7 @@ def init(cell): def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [cell.cellType*0.6+0.1, 1.0-cell.cellType*0.6, 0.3] if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/ex1a_simpleGrowth2D.py b/Examples/ex1a_simpleGrowth2D.py index f195e809..a8d22413 100644 --- a/Examples/ex1a_simpleGrowth2D.py +++ b/Examples/ex1a_simpleGrowth2D.py @@ -36,7 +36,7 @@ def init(cell): def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [cell.cellType*0.6+0.1, 1.0-cell.cellType*0.6, 0.3] if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/ex1a_simpleGrowth2Types.py b/Examples/ex1a_simpleGrowth2Types.py index 3fd04709..20e9d247 100644 --- a/Examples/ex1a_simpleGrowth2Types.py +++ b/Examples/ex1a_simpleGrowth2Types.py @@ -36,7 +36,7 @@ def init(cell): def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [cell.cellType*0.6+0.1, 1.0-cell.cellType*0.6, 0.3] if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/ex1b_simpleGrowth2D.py b/Examples/ex1b_simpleGrowth2D.py index 7f244927..285c60e7 100644 --- a/Examples/ex1b_simpleGrowth2D.py +++ b/Examples/ex1b_simpleGrowth2D.py @@ -36,7 +36,7 @@ def init(cell): def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [cell.cellType*0.6+0.1, 1.0-cell.cellType*0.6, 0.3] if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/ex1b_simpleGrowthRoundCell.py b/Examples/ex1b_simpleGrowthRoundCell.py index f96feea5..1bfd8c99 100644 --- a/Examples/ex1b_simpleGrowthRoundCell.py +++ b/Examples/ex1b_simpleGrowthRoundCell.py @@ -34,7 +34,7 @@ def init(cell): def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [cell.cellType*0.6+0.1, 1.0-cell.cellType*0.6, 0.3] if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/ex2_constGene.py b/Examples/ex2_constGene.py index ff21cb45..baa98232 100644 --- a/Examples/ex2_constGene.py +++ b/Examples/ex2_constGene.py @@ -53,7 +53,7 @@ def specRateCL(): # Add def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [0.1+cell.species[0]/20.0, 0.1, 0.1] # Add/change if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/ex2a_dilution.py b/Examples/ex2a_dilution.py index 93acae3d..013ae89c 100644 --- a/Examples/ex2a_dilution.py +++ b/Examples/ex2a_dilution.py @@ -52,7 +52,7 @@ def specRateCL(): # Add def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [0.1+cell.species[0]*10.0, 0.1, 0.1] # Add/change if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/ex2b_diluteRepression.py b/Examples/ex2b_diluteRepression.py index e203bf91..1b698365 100644 --- a/Examples/ex2b_diluteRepression.py +++ b/Examples/ex2b_diluteRepression.py @@ -57,7 +57,7 @@ def specRateCL(): # Add def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [0.1+cell.species[0], 0.1+cell.species[1]*0.1, 0.1] # Add/change if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/ex3_simpleSignal.py b/Examples/ex3_simpleSignal.py index 6dc58d5f..be408c61 100644 --- a/Examples/ex3_simpleSignal.py +++ b/Examples/ex3_simpleSignal.py @@ -89,7 +89,7 @@ def sigRateCL(): #Add def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [0.1+cell.species[0]/20.0, 0.1, 0.1] if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/ex4_simpleCellCellSignaling.py b/Examples/ex4_simpleCellCellSignaling.py index b88285fb..3eed694f 100644 --- a/Examples/ex4_simpleCellCellSignaling.py +++ b/Examples/ex4_simpleCellCellSignaling.py @@ -99,7 +99,7 @@ def sigRateCL(): #Add def update(cells): #Iterate through each cell and flag cells that reach target size for division - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [0.1+cell.species[1]/20.0, 0.1+cell.species[2]/20.0, 0.1] if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/ex5_colonySector.py b/Examples/ex5_colonySector.py index 35fad734..2764c528 100644 --- a/Examples/ex5_colonySector.py +++ b/Examples/ex5_colonySector.py @@ -30,7 +30,7 @@ def init(cell): cell.n_b = 3 def update(cells): - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [0.1, cell.n_a/3.0, cell.n_b/3.0] if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/ex5_colonySector_3d.py b/Examples/ex5_colonySector_3d.py index 4dfecde4..9848c315 100644 --- a/Examples/ex5_colonySector_3d.py +++ b/Examples/ex5_colonySector_3d.py @@ -32,7 +32,7 @@ def init(cell): cell.n_b = 3 def update(cells): - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [0.1, cell.n_a/3.0, cell.n_b/3.0] if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Examples/load.py b/Examples/load.py index e679f53c..b3b037ea 100644 --- a/Examples/load.py +++ b/Examples/load.py @@ -34,13 +34,13 @@ def setup(sim): # Or pop up a dialog to choose a pickle if dataFileName=='': - print "Please edit the model file to specify a pickle file." - print " -- No data was loaded and there are no cells in this simulation!" + print("Please edit the model file to specify a pickle file.") + print(" -- No data was loaded and there are no cells in this simulation!") else: # Import the data and load into Simulator - print "Loading data from pickle file: %s"%(dataFileName) - import cPickle - data = cPickle.load(open(dataFileName,'r')) + print("Loading data from pickle file: %s"%(dataFileName)) + import pickle + data = pickle.load(open(dataFileName,'r')) sim.loadFromPickle(data) if sim.is_gui: @@ -54,7 +54,7 @@ def init(cell): cell.growthRate = 0.5 def update(cells): - for (id, cell) in cells.iteritems(): + for (id, cell) in cells.items(): cell.color = [1,0,0] if cell.volume > cell.targetVol: cell.divideFlag = True diff --git a/Scripts/CellModellerGUI.py b/Scripts/CellModellerGUI.py index 14f04325..f074440f 100644 --- a/Scripts/CellModellerGUI.py +++ b/Scripts/CellModellerGUI.py @@ -6,8 +6,8 @@ # Tim Rudge # Jan 2011 -from PyQt4.QtGui import QApplication -from PyQt4 import uic +from PyQt5.QtWidgets import QApplication +from PyQt5 import uic import CellModeller.GUI.Renderers from CellModeller import Simulator diff --git a/Scripts/Draw2DPDF.py b/Scripts/Draw2DPDF.py index 34a64488..81b61a95 100644 --- a/Scripts/Draw2DPDF.py +++ b/Scripts/Draw2DPDF.py @@ -8,7 +8,7 @@ from reportlab.lib.colors import Color import numpy -import cPickle +import pickle mxsig0 = 0 @@ -79,7 +79,7 @@ def draw_capsule(self, p, d, l, r, fill_color, stroke_color): self.restoreState() def draw_cells(self): - for id, state in self.states.items(): + for id, state in list(self.states.items()): p = state.pos d = state.dir l = state.length @@ -109,7 +109,7 @@ def draw_signals(self, index=0, scale=0.0192, z=2): self.signal_grid_dim, \ self.signal_levels levels = levels.reshape(dim) - l = map(float,l) + l = list(map(float,l)) for i in range(dim[1]): x = l[0]*i + orig[0] for j in range(dim[2]): @@ -140,7 +140,7 @@ def computeBox(self): mnx = -20 mxy = 20 mny = -20 - for (id,s) in self.states.iteritems(): + for (id,s) in self.states.items(): pos = s.pos l = s.length # add/sub length to keep cell in frame mxx = max(mxx,pos[0]+l) @@ -155,8 +155,8 @@ def computeBox(self): def importPickle(fname): if fname[-7:]=='.pickle': - print 'Importing CellModeller pickle file: %s'%fname - data = cPickle.load(open(fname, 'rb')) + print('Importing CellModeller pickle file: %s'%fname) + data = pickle.load(open(fname, 'rb')) # Check for old-style pickle that is tuple, # just extract cellStates from 1st element @@ -189,17 +189,17 @@ def main(): for infn in infns: # File names if infn[-7:]!='.pickle': - print 'Ignoring file %s, because its not a pickle...'%(infn) + print('Ignoring file %s, because its not a pickle...'%(infn)) continue outfn = string.replace(infn, '.pickle', '.pdf') outfn = os.path.basename(outfn) # Put output in this dir - print 'Processing %s to generate %s'%(infn,outfn) + print('Processing %s to generate %s'%(infn,outfn)) # Import data data = importPickle(infn) if not data: - print "Problem importing data!" + print("Problem importing data!") return # Create a pdf canvas thing @@ -218,7 +218,7 @@ def main(): center = (0,0) # Render pdf - print 'Rendering PDF output to %s'%outfn + print('Rendering PDF output to %s'%outfn) pdf.draw_frame(outfn, world, page, center) if __name__ == "__main__": diff --git a/Scripts/LengthHistogram.py b/Scripts/LengthHistogram.py index 767cfbdd..643182e2 100644 --- a/Scripts/LengthHistogram.py +++ b/Scripts/LengthHistogram.py @@ -3,7 +3,7 @@ import math import numpy as np sys.path.append('.') -import cPickle +import pickle import CellModeller #import matplotlib.pyplot as plt @@ -15,12 +15,12 @@ def rad_pos(cellstate): return np.sqrt(cellstate.pos[0]*cellstate.pos[0]+cellstate.pos[1]*cellstate.pos[1]) def lengthHist(pickle, bins, file=False): - print('opening '+ pickle) - data = cPickle.load(open(pickle,'r')) + print(('opening '+ pickle)) + data = pickle.load(open(pickle,'r')) cs = data['cellStates'] it = iter(cs) n = len(cs) - print 'Number of cells = '+str(n) + print('Number of cells = '+str(n)) lens = [] r = [] for it in cs: @@ -44,7 +44,7 @@ def dirLengthHist(dir,bins,file=False): number = f[5:-7] if file: fout = open('LengthData'+number+'.csv') - print 'step number = ', number + print('step number = ', number) n, lens = lengthHist(dir + f,bins,file) if file: fout.close() diff --git a/Scripts/batch.py b/Scripts/batch.py index f94eaf52..40729604 100644 --- a/Scripts/batch.py +++ b/Scripts/batch.py @@ -20,7 +20,7 @@ def simulate(modfilename, platform, device, steps=50): def main(): # Get module name to load if len(sys.argv)<2: - print "Please specify a model (.py) file" + print("Please specify a model (.py) file") exit(0) else: moduleName = sys.argv[1] @@ -31,17 +31,17 @@ def main(): import pyopencl as cl # Platform platforms = cl.get_platforms() - print "Select OpenCL platform:" + print("Select OpenCL platform:") for i in range(len(platforms)): - print 'press '+str(i)+' for '+str(platforms[i]) - platnum = int(input('Platform Number: ')) + print('press '+str(i)+' for '+str(platforms[i])) + platnum = int(eval(input('Platform Number: '))) # Device devices = platforms[platnum].get_devices() - print "Select OpenCL device:" + print("Select OpenCL device:") for i in range(len(devices)): - print 'press '+str(i)+' for '+str(devices[i]) - devnum = int(input('Device Number: ')) + print('press '+str(i)+' for '+str(devices[i])) + devnum = int(eval(input('Device Number: '))) else: platnum = int(sys.argv[2]) devnum = int(sys.argv[3]) diff --git a/Scripts/batchFile.py b/Scripts/batchFile.py index d62a4a34..01f87c68 100644 --- a/Scripts/batchFile.py +++ b/Scripts/batchFile.py @@ -10,7 +10,7 @@ sys.path.append('./') -print os.getcwd() +print(os.getcwd()) import CellModeller.AdaptiveSimulator @@ -39,14 +39,14 @@ try: os.mkdir(pickleDir) except OSError: - print pickleDir, 'exists' + print(pickleDir, 'exists') pickleSetDir = os.path.join(pickleDir, mod_name) try: os.mkdir(pickleSetDir) except: - print pickleSetDir, 'exists' + print(pickleSetDir, 'exists') folderName = time.strftime('%Y%m%d-%H%M%S', time.localtime()) pickleFileRoot = os.path.join(pickleSetDir, folderName) @@ -56,9 +56,9 @@ def simulate(mod_name, steps=50): - print 'simulate' + print('simulate') sim = Simulator(mod_name, 0.25, None, pickleSteps=50, pickleFileRoot=pickleFileRoot) - print 'start' + print('start') sim.phys.set_cells() sim.phys.calc_cell_geom() diff --git a/Scripts/contactGraph.py b/Scripts/contactGraph.py index d14a4296..7c7cb17d 100644 --- a/Scripts/contactGraph.py +++ b/Scripts/contactGraph.py @@ -2,7 +2,7 @@ import os import math import numpy as np -import cPickle +import pickle import CellModeller import subprocess import string @@ -56,8 +56,8 @@ def draw_graph(self): self.saveState() self.setLineWidth(0.003*units.cm) self.setStrokeColor((0.0,0.0,0.0)) - positions = networkx.get_node_attributes(G,'pos').values() - colors = networkx.get_node_attributes(G,'color').values() + positions = list(networkx.get_node_attributes(G,'pos').values()) + colors = list(networkx.get_node_attributes(G,'color').values()) for u,v,di in self.network.edges_iter(data=True): self.drawEdge(positions[u],positions[v]) for n in self.network.nodes_iter(): @@ -104,13 +104,13 @@ def get_current_contacts(G, data): G = networkx.Graph() fname = sys.argv[1] -data = cPickle.load(open(fname,'rb')) +data = pickle.load(open(fname,'rb')) cs = data['cellStates'] it = iter(cs) n = len(cs) oname = fname.replace('.pickle','_graph.pdf') -print "num_cells = "+str(n) +print("num_cells = "+str(n)) cell_type={} pos_dict={} @@ -120,13 +120,13 @@ def get_current_contacts(G, data): get_current_contacts(G, data) -print "num_contacts = " + str(networkx.number_of_edges(G)) -degrees = G.degree().values() -print "mean degree = " + str(np.mean(degrees)) +print("num_contacts = " + str(networkx.number_of_edges(G))) +degrees = list(G.degree().values()) +print("mean degree = " + str(np.mean(degrees))) -if networkx.get_edge_attributes(G,'color').items(): - edges,ecolor = zip(*networkx.get_edge_attributes(G,'color').items()) -ncolor = networkx.get_node_attributes(G,'color').values() +if list(networkx.get_edge_attributes(G,'color').items()): + edges,ecolor = list(zip(*list(networkx.get_edge_attributes(G,'color').items()))) +ncolor = list(networkx.get_node_attributes(G,'color').values()) pdf = CellModellerPDFGenerator(oname, G, bg_color) world = (120,120) diff --git a/Scripts/multi_batch.py b/Scripts/multi_batch.py index 38ecf6fb..b1058302 100644 --- a/Scripts/multi_batch.py +++ b/Scripts/multi_batch.py @@ -20,7 +20,7 @@ def simulate(modfilename, platform, device, steps=50): def main(): # Get module name to load if len(sys.argv)<2: - print "Please specify a model (.py) file" + print("Please specify a model (.py) file") exit(0) else: moduleName = sys.argv[1] @@ -31,17 +31,17 @@ def main(): import pyopencl as cl # Platform platforms = cl.get_platforms() - print "Select OpenCL platform:" + print("Select OpenCL platform:") for i in range(len(platforms)): - print 'press '+str(i)+' for '+str(platforms[i]) - platnum = int(input('Platform Number: ')) + print('press '+str(i)+' for '+str(platforms[i])) + platnum = int(eval(input('Platform Number: '))) # Device devices = platforms[platnum].get_devices() - print "Select OpenCL device:" + print("Select OpenCL device:") for i in range(len(devices)): - print 'press '+str(i)+' for '+str(devices[i]) - devnum = int(input('Device Number: ')) + print('press '+str(i)+' for '+str(devices[i])) + devnum = int(eval(input('Device Number: '))) else: platnum = int(sys.argv[2]) devnum = int(sys.argv[3]) diff --git a/Scripts/printTiming.py b/Scripts/printTiming.py index 38953c48..8cdd128b 100644 --- a/Scripts/printTiming.py +++ b/Scripts/printTiming.py @@ -1,18 +1,18 @@ import sys import os sys.path.append('.') -import cPickle +import pickle import CellModeller dir = os.path.join('data', sys.argv[1]) -print "No. cells\ttime (s)" -print "-------------------" +print("No. cells\ttime (s)") +print("-------------------") for f in os.listdir(dir): if 'pickle' in f: ff = os.path.join(dir,f) - (cs,lin) = cPickle.load(open(ff,'r')) + (cs,lin) = pickle.load(open(ff,'r')) n = len(cs) t = os.path.getmtime(ff) - print "%i\t%f"%(n,t) + print("%i\t%f"%(n,t)) diff --git a/Scripts/spatial_analyze.py b/Scripts/spatial_analyze.py index b178ea1b..15b86ecb 100644 --- a/Scripts/spatial_analyze.py +++ b/Scripts/spatial_analyze.py @@ -3,12 +3,12 @@ import math import numpy as np sys.path.append('.') -import cPickle +import pickle import CellModeller import matplotlib.pyplot as plt pname= sys.argv[1] -print('opening '+ pname) +print(('opening '+ pname)) fout=open('spatial.txt', "w") fout.write("r spec_level \n") @@ -18,12 +18,12 @@ narray=np.zeros(bin_num) specArray=np.zeros(bin_num) -data = cPickle.load(open(pname,'r')) +data = pickle.load(open(pname,'r')) cs = data['cellStates'] it = iter(cs) n = len(cs) -rArray = np.multiply(range(0,bin_num),rad_max/bin_num) +rArray = np.multiply(list(range(0,bin_num)),rad_max/bin_num) for it in cs: r = np.sqrt(cs[it].pos[0]*cs[it].pos[0]+cs[it].pos[1]*cs[it].pos[1]) diff --git a/setup.py b/setup.py index 17d59036..78a23b13 100644 --- a/setup.py +++ b/setup.py @@ -22,8 +22,8 @@ setup(name='CellModeller', - install_requires=['numpy==1.9.2', 'scipy', 'pyopengl', 'pyopencl==2014.1', 'reportlab', 'matplotlib'], - setup_requires=['numpy==1.9.2', 'scipy', 'pyopengl', 'pyopencl==2014.1', 'reportlab', 'matplotlib'], + install_requires=['numpy', 'scipy', 'pyopengl', 'pyopencl', 'reportlab', 'matplotlib'], + setup_requires=['numpy', 'scipy', 'pyopengl', 'pyopencl', 'reportlab', 'matplotlib'], #setup_requires=['python=2'], #setup_requires=['numpy', 'pyopengl', 'mako', 'pyopencl'], packages=['CellModeller', From f5614fe87c1aa64abbaf7b1a1e8ea8d6222280bd Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Mon, 30 Mar 2020 22:35:46 -0300 Subject: [PATCH 02/26] Clean up commented code --- CellModeller/Simulator.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CellModeller/Simulator.py b/CellModeller/Simulator.py index 17fd7cd0..a14a1e56 100644 --- a/CellModeller/Simulator.py +++ b/CellModeller/Simulator.py @@ -107,12 +107,6 @@ def __init__(self, \ self.dataOutputInitialised=False self.outputDirName = outputDirName self.setSaveOutput(saveOutput) - ''' - self.saveOutput = saveOutput - if self.saveOutput: - self.outputSteps = outputSteps - self.init_data_output(outputFileDir) - ''' # Call the user-defined setup function on ourself self.module.setup(self) From 692af9d30b4e503235fe431e6e68b762e33921ac Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Mon, 30 Mar 2020 22:36:51 -0300 Subject: [PATCH 03/26] Fix for new QFileDialog return type. Increase size of grid in GUI, and size of axes --- CellModeller/GUI/PyGLCMViewer.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/CellModeller/GUI/PyGLCMViewer.py b/CellModeller/GUI/PyGLCMViewer.py index 8ab6babe..662bd73f 100644 --- a/CellModeller/GUI/PyGLCMViewer.py +++ b/CellModeller/GUI/PyGLCMViewer.py @@ -54,6 +54,7 @@ def setSimulator(self, sim): self.frameNo += 1 # Make GUI button match simulator state for saving pickles self.setSavePicklesToggle.emit(sim.saveOutput) + print('saveOutput ', sim.saveOutput) # Get rid of any selected cell id self.selectedName = -1 @@ -145,9 +146,10 @@ def reset(self): @pyqtSlot() def loadPickle(self): - qs = QFileDialog.getOpenFileName(self, 'Load pickle file', '', '*.pickle') + qs,_ = QFileDialog.getOpenFileName(self, 'Load pickle file', '', '*.pickle') if qs and self.getOpenCLPlatDev(): filename = str(qs) + print(filename) data = pickle.load(open(filename,'rb')) if isinstance(data, dict): self.modName = data['moduleName'] @@ -160,9 +162,9 @@ def loadPickle(self): clDeviceNum=self.clDeviceNum, \ is_gui=True) - self.setSimulator(sim) self.loadingFromPickle = True - self.sim.loadFromPickle(data) + sim.loadFromPickle(data) + self.setSimulator(sim) # Note: the pickle loaded contains the stepNum, hence we now # need to set the GUI frameNo to match self.frameNo = self.sim.stepNum @@ -174,9 +176,10 @@ def loadPickle(self): @pyqtSlot() def load(self): - qs = QFileDialog.getOpenFileName(self, 'Load Python module', '', '*.py') + qs,_ = QFileDialog.getOpenFileName(self, 'Load Python module', '', '*.py') if qs: modfile = str(qs) + print(modfile) self.loadModelFile(modfile) def loadModelFile(self, modname): @@ -261,11 +264,11 @@ def paintGL(self): glEnable(GL_LINE_SMOOTH) glLineWidth(1.0) glBegin(GL_LINES) - for i in range(5): - glVertex(-20, (i-2)*10) - glVertex(20, (i-2)*10) - glVertex((i-2)*10, -20) - glVertex((i-2)*10, 20) + for i in range(25): + glVertex(-120, (i-12)*10) + glVertex(120, (i-12)*10) + glVertex((i-12)*10, -120) + glVertex((i-12)*10, 120) glEnd() # Draw x,y,z axes @@ -273,13 +276,13 @@ def paintGL(self): glBegin(GL_LINES) glColor3f(1.0,0.0,0.0) glVertex(0,0,0) - glVertex(5,0,0) + glVertex(25,0,0) glColor3f(0.0,1.0,0.0) glVertex(0,0,0) - glVertex(0,5,0) + glVertex(0,25,0) glColor3f(0.0,0.0,1.0) glVertex(0,0,0) - glVertex(0,0,5) + glVertex(0,0,25) glEnd() glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) From 08a7c89b4aad72dde34cc86afc29e1039872b0bb Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Wed, 1 Apr 2020 20:06:49 -0300 Subject: [PATCH 04/26] Add all requirements to setup.py --- setup.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 78a23b13..b0240950 100644 --- a/setup.py +++ b/setup.py @@ -22,10 +22,8 @@ setup(name='CellModeller', - install_requires=['numpy', 'scipy', 'pyopengl', 'pyopencl', 'reportlab', 'matplotlib'], - setup_requires=['numpy', 'scipy', 'pyopengl', 'pyopencl', 'reportlab', 'matplotlib'], - #setup_requires=['python=2'], - #setup_requires=['numpy', 'pyopengl', 'mako', 'pyopencl'], + install_requires=['numpy', 'scipy', 'pyopengl', 'mako', 'pyqt5', 'pyopencl', 'reportlab', 'matplotlib'], + setup_requires=['numpy', 'scipy', 'pyopengl', 'mako', 'pyqt5', 'pyopencl', 'reportlab', 'matplotlib'], packages=['CellModeller', 'CellModeller.Biophysics', 'CellModeller.Biophysics.BacterialModels', @@ -35,5 +33,6 @@ 'CellModeller.Signalling', 'CellModeller.GUI'], package_data={'':['*.cl','*.ui']}, + python_requires='>=3', version=str(version_git) ) From 6031deca64f64a19af0e792f45937d43b1e5c549 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Fri, 3 Apr 2020 22:56:34 -0300 Subject: [PATCH 05/26] Do not use native file dialogs, fails on Ubuntu --- CellModeller/GUI/PyGLCMViewer.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CellModeller/GUI/PyGLCMViewer.py b/CellModeller/GUI/PyGLCMViewer.py index 662bd73f..75b8b16b 100644 --- a/CellModeller/GUI/PyGLCMViewer.py +++ b/CellModeller/GUI/PyGLCMViewer.py @@ -146,7 +146,9 @@ def reset(self): @pyqtSlot() def loadPickle(self): - qs,_ = QFileDialog.getOpenFileName(self, 'Load pickle file', '', '*.pickle') + options = QFileDialog.Options() + options |= QFileDialog.DontUseNativeDialog + qs,_ = QFileDialog.getOpenFileName(self, 'Load pickle file', '', '*.pickle', options=options) if qs and self.getOpenCLPlatDev(): filename = str(qs) print(filename) @@ -176,7 +178,9 @@ def loadPickle(self): @pyqtSlot() def load(self): - qs,_ = QFileDialog.getOpenFileName(self, 'Load Python module', '', '*.py') + options = QFileDialog.Options() + options |= QFileDialog.DontUseNativeDialog + qs,_ = QFileDialog.getOpenFileName(self, 'Load Python module', '', '*.py', options=options) if qs: modfile = str(qs) print(modfile) From ebd001101f37ae9d8d22f64d3a11ebad0eefccb2 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Sun, 19 Apr 2020 13:20:04 -0400 Subject: [PATCH 06/26] Fix cell selection for retina/hi dpi displays --- CellModeller/GUI/PyGLCMViewer.py | 6 + CellModeller/GUI/PyGLWidget.py | 11 +- CellModeller/GUI/Renderers.py | 1856 ++++++++++++------------ Examples/ex1b_simpleGrowthRoundCell.py | 2 +- Examples/ex5_colonySector.py | 16 +- Scripts/CellModellerGUI.py | 2 + 6 files changed, 961 insertions(+), 932 deletions(-) diff --git a/CellModeller/GUI/PyGLCMViewer.py b/CellModeller/GUI/PyGLCMViewer.py index 75b8b16b..0dcd00ba 100644 --- a/CellModeller/GUI/PyGLCMViewer.py +++ b/CellModeller/GUI/PyGLCMViewer.py @@ -42,9 +42,15 @@ def __init__(self, parent = None): self.translate([0,0,20]) self.rotate([1,0,0],-45) + # Assume no pixel scaling unless explicitly set + self.pix_ratio = 1. + def help(self): pass + def setPixelRatio(self, ratio): + self.pix_ratio = ratio + def setSimulator(self, sim): if self.sim: del self.sim diff --git a/CellModeller/GUI/PyGLWidget.py b/CellModeller/GUI/PyGLWidget.py index 628ed0b7..e10c9d11 100644 --- a/CellModeller/GUI/PyGLWidget.py +++ b/CellModeller/GUI/PyGLWidget.py @@ -67,7 +67,8 @@ def __init__(self, parent = None): self.last_point_ok_ = False self.last_point_3D_ = [1.0, 0.0, 0.0] self.isInRotation_ = False - self.pickSize = 3 + self.pickSize = 18 + self.pix_ratio = 1. # connections #self.signalGLMatrixChanged.connect(self.printModelViewMatrix) @@ -110,8 +111,9 @@ def set_pick_projection(self, x, y, _near, _far, _fovy): self.makeCurrent() glMatrixMode( GL_PROJECTION ) glLoadIdentity() - viewport =glGetIntegerv(GL_VIEWPORT) - gluPickMatrix(x, viewport[3]-y, self.pickSize, self.pickSize, viewport); + viewport = glGetIntegerv(GL_VIEWPORT) + #gluPickMatrix(x, viewport[3]-y, self.pickSize, self.pickSize, viewport); + gluPickMatrix(x*self.pix_ratio, viewport[3]-y*self.pix_ratio, self.pickSize, self.pickSize, viewport); gluPerspective( self.fovy_, float(self.width()) / float(self.height()), self.near_, self.far_ ) def set_center(self, _cog): @@ -238,13 +240,16 @@ def selectName(self, point): buf = glRenderMode(GL_RENDER) selectedName = -1 closest_z = 1.0 + print('buf ', buf) for hit_record in buf: min_depth, max_depth, names = hit_record + print('Names ', names) if min_depth < closest_z: closest_z = min_depth for name in names: if name: selectedName = name + print('Selected name ', selectedName) glMatrixMode( GL_PROJECTION ) glPopMatrix() return selectedName diff --git a/CellModeller/GUI/Renderers.py b/CellModeller/GUI/Renderers.py index 52a6501c..7bb02441 100644 --- a/CellModeller/GUI/Renderers.py +++ b/CellModeller/GUI/Renderers.py @@ -208,930 +208,946 @@ def render_gl(self, selection=None): class GLBacteriumRenderer: - def __init__(self, sim, properties=None, scales = None): - self.ncells_list = 0 - self.ncells_names_list = 0 - self.dlist = None - self.dlist_names = None - self.cellcol = [1, 1, 1] - self.sim = sim - self.quad = gluNewQuadric() - self.properties = properties - self.scales = scales - - def init_gl(self): - pass - - #def render_text(self, position, textString, fontSize): - # pygame.font.init() - # font = pygame.font.Font (None, fontSize) - # textSurface = font.render(textString, True, (0,0,0,225), (255,255,255,255)) - # textData = pygame.image.tostring(textSurface, "RGBA", True) - # glRasterPos3d(*position) - # glDrawPixels(textSurface.get_width(), textSurface.get_height(), GL_RGBA, GL_UNSIGNED_BYTE, textData) - - def build_list(self, cells): - if self.dlist: - glDeleteLists(self.dlist, 1) - index = glGenLists(1) - glNewList(index, GL_COMPILE) - self.render_cells() - glEndList() - self.dlist = index - - def build_list_names(self, cells): - if self.dlist_names: - glDeleteLists(self.dlist_names, 1) - index = glGenLists(1) - glNewList(index, GL_COMPILE) - self.render_cell_names() - glEndList() - self.dlist_names = index - - def render_gl(self, selection=None): - cells = self.sim.cellStates.values() - states = self.sim.cellStates.items() - # FIXED ============================================================================= - # Before, the renderer would only draw cells when the number of cells changed. - # Now it draws them whenever render_gl is called (by paintGL in PyGLCMViewer.py) - self.build_list(cells) - self.ncells_list = len(cells) - - #if len(cells)!=self.ncells_list: - # self.build_list(cells) - # self.ncells_list = len(cells) - #==================================================================================== - glCallList(self.dlist) - #for cell in cells: self.render_cell(cell, selection) - - - def renderNames_gl(self, selection=None): - cells = self.sim.cellStates.values() - if len(cells)!=self.ncells_names_list: - self.build_list_names(cells) - self.ncells_names_list = len(cells) - glCallList(self.dlist_names) - #for cell in cells: self.render_cell_name(cell, selection) - - - def render_cell_names(self): - # glDisable(GL_DEPTH_TEST) - glDisable(GL_LIGHTING) - for cell in self.sim.cellStates.values(): - l = cell.length - r = cell.radius - - (e1,e2) = cell.ends - ae1 = numpy.array(e1) - ae2 = numpy.array(e2) - zaxis = numpy.array([0,0,1]) - caxis = numpy.array(cell.dir) #(ae2-ae1)/l - rotaxis = numpy.cross(caxis, zaxis) - rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) - - cid = cell.id - glPushName(cid) - - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1[0],e1[1],e1[2]) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - glPushMatrix() - glTranslatef(e2[0],e2[1],e2[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - glPopName() - - glEnable(GL_LIGHTING) - - - def render_cells(self, selection=None): - - # PLACEHOLDER - - #glDisable(GL_DEPTH_TEST) - glDisable(GL_LIGHTING) - cells = self.sim.cellStates.values() - for cell in cells: - l = cell.length - #r = cell.radius*2.0 - r = cell.radius - - (e1,e2) = cell.ends - ae1 = numpy.array(e1) - ae2 = numpy.array(e2) - zaxis = numpy.array([0,0,1]) - caxis = numpy.array(cell.dir) #(ae2-ae1)/l - rotaxis = numpy.cross(caxis, zaxis) - rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) - - cid = cell.id - cidx = cell.idx - if False: - self.render_text(0.5*(e1+e2), str(cidx), 24) - - if selection==cid: - cellcol = [1,0,0] - else: - cellcol = cell.color #self.cellcol #[random.uniform(0,1), random.uniform(0,1), random.uniform(0,1)] - if self.properties: - cellcol = [] - for p in self.properties: - if hasattr(cell,p): - cellcol.append(getattr(cell,p)) - else: - cellcol.append(0) - for i in range(3): - cellcol[i] *= self.scales[i] - cellcol[i] = min(1,cellcol[i]) - - # draw the outlines antialiased in black - glColor3f(0.0, 0.0, 0.0) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_LINE_SMOOTH) - glLineWidth(8.0) - # draw wireframe for back facing polygons and cull front-facing ones - glPolygonMode(GL_BACK, GL_FILL) - glEnable(GL_CULL_FACE) - glCullFace(GL_FRONT) - glDepthFunc(GL_LEQUAL) - - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1[0],e1[1],e1[2]) - gluSphere(self.quad, r, 8, 8) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2[0],e2[1],e2[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - - glDepthFunc(GL_LESS) - glDisable(GL_CULL_FACE) - glPolygonMode(GL_FRONT, GL_FILL) - glDisable(GL_LINE_SMOOTH) - glDisable(GL_BLEND) - - glColor3fv(cellcol) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1[0],e1[1],e1[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - #glScalef(1.25,1.0,1.0) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l*1.25, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2[0],e2[1],e2[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - #glColor3f(68.0 / 256, 81.0 / 256, 44.0 / 256) - #glLineWidth(2) - #glBegin(GL_LINES) - #glVertex3f(e1[0], e1[1], e1[2]) - #glVertex3f(e2[0], e2[1], e2[2]) - #glEnd() - # - #glColor3f(1.0, 1.0, 0.0) - #glPointSize(3) - #glBegin(GL_POINTS) - #glVertex3f(e1[0], e1[1], e1[2]) - #glVertex3f(e2[0], e2[1], e2[2]) - #glEnd() - - # draw contact points - if False: #hasattr(cells[0], 'contacts'): - glDisable(GL_DEPTH_TEST) - glDisable(GL_LIGHTING) - for cell in cells: - contacts = cell.contacts - glBegin(GL_LINES) - for ct in contacts: - glColor3fv(ct[6:9]) - glVertex3fv(ct[0:3]) - glVertex3fv(ct[3:6]) - glEnd() - glBegin(GL_POINTS) - for ct in contacts: - glColor3fv(ct[6:9]) - glVertex3fv(ct[0:3]) - glEnd() - glEnable(GL_DEPTH_TEST) - glEnable(GL_LIGHTING) + def __init__(self, sim, properties=None, scales = None): + self.ncells_list = 0 + self.ncells_names_list = 0 + self.dlist = None + self.dlist_names = None + self.cellcol = [1, 1, 1] + self.sim = sim + self.quad = gluNewQuadric() + self.properties = properties + self.scales = scales + + def init_gl(self): + pass + + #def render_text(self, position, textString, fontSize): + # pygame.font.init() + # font = pygame.font.Font (None, fontSize) + # textSurface = font.render(textString, True, (0,0,0,225), (255,255,255,255)) + # textData = pygame.image.tostring(textSurface, "RGBA", True) + # glRasterPos3d(*position) + # glDrawPixels(textSurface.get_width(), textSurface.get_height(), GL_RGBA, GL_UNSIGNED_BYTE, textData) + + def build_list(self, cells): + if self.dlist: + glDeleteLists(self.dlist, 1) + index = glGenLists(1) + glNewList(index, GL_COMPILE) + self.render_cells() + glEndList() + self.dlist = index + + def build_list_names(self, cells): + if self.dlist_names: + glDeleteLists(self.dlist_names, 1) + index = glGenLists(1) + glNewList(index, GL_COMPILE) + self.render_cell_names() + glEndList() + self.dlist_names = index + + def render_gl(self, selection=None): + cells = self.sim.cellStates.values() + states = self.sim.cellStates.items() + # FIXED ============================================================================= + # Before, the renderer would only draw cells when the number of cells changed. + # Now it draws them whenever render_gl is called (by paintGL in PyGLCMViewer.py) + if len(cells)!=self.ncells_list or len(cells)<500: + self.build_list(cells) + self.ncells_list = len(cells) + + #if len(cells)!=self.ncells_list: + # self.build_list(cells) + # self.ncells_list = len(cells) + #==================================================================================== + glCallList(self.dlist) + #for cell in cells: self.render_cell(cell, selection) + + + def renderNames_gl(self, selection=None): + cells = self.sim.cellStates.values() + if len(cells)!=self.ncells_names_list or len(cells)<500: + self.build_list_names(cells) + self.ncells_names_list = len(cells) + glCallList(self.dlist_names) + #for cell in cells: self.render_cell_name(cell, selection) + + + def render_cell_names(self): + # glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + for cell in self.sim.cellStates.values(): + l = cell.length + r = cell.radius + + (e1,e2) = cell.ends + ae1 = numpy.array(e1) + ae2 = numpy.array(e2) + zaxis = numpy.array([0,0,1]) + caxis = numpy.array(cell.dir) #(ae2-ae1)/l + rotaxis = numpy.cross(caxis, zaxis) + rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) + + cid = cell.id + glPushName(cid) + + ''' + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + ''' + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glPopName() + + glEnable(GL_LIGHTING) + + def render_cells(self, selection=None): + + # PLACEHOLDER + + #glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + cells = self.sim.cellStates.values() + for cell in cells: + l = cell.length + #r = cell.radius*2.0 + r = cell.radius + + (e1,e2) = cell.ends + ae1 = numpy.array(e1) + ae2 = numpy.array(e2) + zaxis = numpy.array([0,0,1]) + caxis = numpy.array(cell.dir) #(ae2-ae1)/l + rotaxis = numpy.cross(caxis, zaxis) + rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) + + cid = cell.id + cidx = cell.idx + if False: + self.render_text(0.5*(e1+e2), str(cidx), 24) + + if selection==cid: + cellcol = [1,0,0] + else: + cellcol = cell.color #self.cellcol #[random.uniform(0,1), random.uniform(0,1), random.uniform(0,1)] + if self.properties: + cellcol = [] + for p in self.properties: + if hasattr(cell,p): + cellcol.append(getattr(cell,p)) + else: + cellcol.append(0) + for i in range(3): + cellcol[i] *= self.scales[i] + cellcol[i] = min(1,cellcol[i]) + + # draw the outlines antialiased in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + #glColor3f(68.0 / 256, 81.0 / 256, 44.0 / 256) + #glLineWidth(2) + #glBegin(GL_LINES) + #glVertex3f(e1[0], e1[1], e1[2]) + #glVertex3f(e2[0], e2[1], e2[2]) + #glEnd() + # + #glColor3f(1.0, 1.0, 0.0) + #glPointSize(3) + #glBegin(GL_POINTS) + #glVertex3f(e1[0], e1[1], e1[2]) + #glVertex3f(e2[0], e2[1], e2[2]) + #glEnd() + + # draw contact points + if False: #hasattr(cells[0], 'contacts'): + glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + for cell in cells: + contacts = cell.contacts + glBegin(GL_LINES) + for ct in contacts: + glColor3fv(ct[6:9]) + glVertex3fv(ct[0:3]) + glVertex3fv(ct[3:6]) + glEnd() + glBegin(GL_POINTS) + for ct in contacts: + glColor3fv(ct[6:9]) + glVertex3fv(ct[0:3]) + glEnd() + glEnable(GL_DEPTH_TEST) + glEnable(GL_LIGHTING) class GLBacteriumRendererWithPeriodicImages: - def __init__(self, sim, properties=None, scales = None): - self.ncells_list = 0 - self.ncells_names_list = 0 - self.dlist = None - self.dlist_names = None - self.cellcol = [1, 1, 1] - self.sim = sim - self.quad = gluNewQuadric() - self.properties = properties - self.scales = scales - - def init_gl(self): - pass - - def build_list(self, cells): - if self.dlist: - glDeleteLists(self.dlist, 1) - index = glGenLists(1) - glNewList(index, GL_COMPILE) - self.render_cells() - textString = 'CellModeller4 Development Version' #self.render_text(position, textString, 40) - position = numpy.array([-40.0,30.0,0.0]) - glEndList() - self.dlist = index - - def build_list_names(self, cells): - if self.dlist_names: - glDeleteLists(self.dlist_names, 1) - index = glGenLists(1) - glNewList(index, GL_COMPILE) - self.render_cell_names() - glEndList() - self.dlist_names = index - - def render_gl(self, selection=None): - cells = self.sim.cellStates.values() - states = self.sim.cellStates.items() - # FIXED ============================================================================= - # Before, the renderer would only draw cells when the number of cells changed. - # Now it draws them whenever render_gl is called (by paintGL in PyGLCMViewer.py) - - names = False - if not names: - self.build_list(cells) - self.ncells_list = len(cells) - glCallList(self.dlist) - else: - # added to try and render cell ids - self.build_list_names(cells) - self.ncells_names_list = len(cells) - glCallList(self.dlist_names) - - #if len(cells)!=self.ncells_list: - # self.build_list(cells) - # self.ncells_list = len(cells) - #==================================================================================== - #glCallList(self.dlist) - #glCallList(self.dlist_names) - #for cell in cells: self.render_cell(cell, selection) - - - def renderNames_gl(self, selection=None): - cells = self.sim.cellStates.values() - if len(cells)!=self.ncells_names_list: - self.build_list_names(cells) - self.ncells_names_list = len(cells) - glCallList(self.dlist_names) - #for cell in cells: self.render_cell_name(cell, selection) - - - def render_cell_names(self): - # glDisable(GL_DEPTH_TEST) - glDisable(GL_LIGHTING) - for cell in self.sim.cellStates.values(): - l = cell.length - r = cell.radius - - (e1,e2) = cell.ends - ae1 = numpy.array(e1) - ae2 = numpy.array(e2) - zaxis = numpy.array([0,0,1]) - caxis = numpy.array(cell.dir) #(ae2-ae1)/l - rotaxis = numpy.cross(caxis, zaxis) - rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) - - cid = cell.id - glPushName(cid) - - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1[0],e1[1],e1[2]) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - glPushMatrix() - glTranslatef(e2[0],e2[1],e2[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - glPopName() - - glEnable(GL_LIGHTING) - - #def render_text(self, position, textString, fontSize): - # pygame.font.init() - # font = pygame.font.Font (None, fontSize) - # textSurface = font.render(textString, True, (0,0,0,225), (255,255,255,255)) - # textData = pygame.image.tostring(textSurface, "RGBA", True) - # glRasterPos3d(*position) - # glDrawPixels(textSurface.get_width(), textSurface.get_height(), GL_RGBA, GL_UNSIGNED_BYTE, textData) - # #glClear(GL_DEPTH_BUFFER_BIT) - - def render_cells(self, selection=None): - #glDisable(GL_DEPTH_TEST) - glDisable(GL_LIGHTING) - cells = self.sim.cellStates.values() - for cell in cells: - l = cell.length - #r = cell.radius*2.0 - r = cell.radius - - (e1,e2) = cell.ends - - L_x = self.sim.phys.max_x_coord - self.sim.phys.min_x_coord - L_y = self.sim.phys.max_y_coord - self.sim.phys.min_y_coord - offset_x = numpy.array([L_x,0.0,0.0]) - offset_y = numpy.array([0.0,L_y,0.0]) - - # top image - e1_t = e1 + offset_y - e2_t = e2 + offset_y - # bottom image - e1_b = e1 - offset_y - e2_b = e2 - offset_y - # left image - e1_l = e1 - offset_x - e2_l = e2 - offset_x - # right image - e1_r = e1 + offset_x - e2_r = e2 + offset_x - - zaxis = numpy.array([0,0,1]) - caxis = numpy.array(cell.dir) #(ae2-ae1)/l - rotaxis = numpy.cross(caxis, zaxis) - rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) - - cid = cell.id - #======================================================== Adding cell labels - cidx = cell.idx - #if self.sim.render_labels: - if False: - self.render_text(0.5*(e1+e2), str(cidx), 24) - #======================================================== - if selection==cid: - cellcol = [1,0,0] - else: - cellcol = cell.color #self.cellcol #[random.uniform(0,1), random.uniform(0,1), random.uniform(0,1)] - if self.properties: - cellcol = [] - for p in self.properties: - if hasattr(cell,p): - cellcol.append(getattr(cell,p)) - else: - cellcol.append(0) - for i in range(3): - cellcol[i] *= self.scales[i] - cellcol[i] = min(1,cellcol[i]) - - # image cells are grey - cellcol2 = numpy.array([0.9,0.9,0.9]) - - # main image - # draw the outlines initialized in black - glColor3f(0.0, 0.0, 0.0) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_LINE_SMOOTH) - glLineWidth(8.0) - # draw wireframe for back facing polygons and cull front-facing ones - glPolygonMode(GL_BACK, GL_FILL) - glEnable(GL_CULL_FACE) - glCullFace(GL_FRONT) - glDepthFunc(GL_LEQUAL) - - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1[0],e1[1],e1[2]) - gluSphere(self.quad, r, 8, 8) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2[0],e2[1],e2[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - # FIXME ========================================= - #() - #================================================ - - glDepthFunc(GL_LESS) - glDisable(GL_CULL_FACE) - glPolygonMode(GL_FRONT, GL_FILL) - glDisable(GL_LINE_SMOOTH) - glDisable(GL_BLEND) - - glColor3fv(cellcol) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1[0],e1[1],e1[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - #glScalef(1.25,1.0,1.0) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l*1.25, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2[0],e2[1],e2[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - # draw contact points - #========================================================= - if hasattr(cells[0], 'contacts'): - #========================================================= used to always be false but it won't work anyway - see below - glDisable(GL_DEPTH_TEST) - glDisable(GL_LIGHTING) - for cell in cells: - contacts = cell.contacts # this won't work because cellStates no longer have a contacts attribute - glBegin(GL_LINES) - for ct in contacts: - glColor3fv(ct[6:9]) - glVertex3fv(ct[0:3]) - glVertex3fv(ct[3:6]) - glEnd() - glBegin(GL_POINTS) - for ct in contacts: - glColor3fv(ct[6:9]) - glVertex3fv(ct[0:3]) - glEnd() - glEnable(GL_DEPTH_TEST) - glEnable(GL_LIGHTING) - - # top image - #========================================== - # draw the outlines initialized in black - glColor3f(0.0, 0.0, 0.0) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_LINE_SMOOTH) - glLineWidth(8.0) - - # draw wireframe for back facing polygons and cull front-facing ones - glPolygonMode(GL_BACK, GL_FILL) - glEnable(GL_CULL_FACE) - glCullFace(GL_FRONT) - glDepthFunc(GL_LEQUAL) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_t[0],e1_t[1],e1_t[2]) - gluSphere(self.quad, r, 8, 8) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_t[0],e2_t[1],e2_t[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - glDepthFunc(GL_LESS) - glDisable(GL_CULL_FACE) - glPolygonMode(GL_FRONT, GL_FILL) - glDisable(GL_LINE_SMOOTH) - glDisable(GL_BLEND) - - glColor3fv(cellcol2) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_t[0],e1_t[1],e1_t[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - #glScalef(1.25,1.0,1.0) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l*1.25, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_t[0],e2_t[1],e2_t[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - #============================================ - - # bottom image - #========================================== - # draw the outlines initialized in black - glColor3f(0.0, 0.0, 0.0) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_LINE_SMOOTH) - glLineWidth(8.0) - - # draw wireframe for back facing polygons and cull front-facing ones - glPolygonMode(GL_BACK, GL_FILL) - glEnable(GL_CULL_FACE) - glCullFace(GL_FRONT) - glDepthFunc(GL_LEQUAL) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_b[0],e1_b[1],e1_b[2]) - gluSphere(self.quad, r, 8, 8) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_b[0],e2_b[1],e2_b[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - glDepthFunc(GL_LESS) - glDisable(GL_CULL_FACE) - glPolygonMode(GL_FRONT, GL_FILL) - glDisable(GL_LINE_SMOOTH) - glDisable(GL_BLEND) - - glColor3fv(cellcol2) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_b[0],e1_b[1],e1_b[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - #glScalef(1.25,1.0,1.0) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l*1.25, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_b[0],e2_b[1],e2_b[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - #============================================ - - # left image - #========================================== - # draw the outlines initialized in black - glColor3f(0.0, 0.0, 0.0) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_LINE_SMOOTH) - glLineWidth(8.0) - - # draw wireframe for back facing polygons and cull front-facing ones - glPolygonMode(GL_BACK, GL_FILL) - glEnable(GL_CULL_FACE) - glCullFace(GL_FRONT) - glDepthFunc(GL_LEQUAL) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_l[0],e1_l[1],e1_l[2]) - gluSphere(self.quad, r, 8, 8) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_l[0],e2_l[1],e2_l[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - glDepthFunc(GL_LESS) - glDisable(GL_CULL_FACE) - glPolygonMode(GL_FRONT, GL_FILL) - glDisable(GL_LINE_SMOOTH) - glDisable(GL_BLEND) - - glColor3fv(cellcol2) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_l[0],e1_l[1],e1_l[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - #glScalef(1.25,1.0,1.0) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l*1.25, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_l[0],e2_l[1],e2_l[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - #============================================ - # right image - #========================================== - # draw the outlines initialized in black - glColor3f(0.0, 0.0, 0.0) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_LINE_SMOOTH) - glLineWidth(8.0) - - # draw wireframe for back facing polygons and cull front-facing ones - glPolygonMode(GL_BACK, GL_FILL) - glEnable(GL_CULL_FACE) - glCullFace(GL_FRONT) - glDepthFunc(GL_LEQUAL) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_r[0],e1_r[1],e1_r[2]) - gluSphere(self.quad, r, 8, 8) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_r[0],e2_r[1],e2_r[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - glDepthFunc(GL_LESS) - glDisable(GL_CULL_FACE) - glPolygonMode(GL_FRONT, GL_FILL) - glDisable(GL_LINE_SMOOTH) - glDisable(GL_BLEND) - - glColor3fv(cellcol2) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_r[0],e1_r[1],e1_r[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - #glScalef(1.25,1.0,1.0) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l*1.25, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_r[0],e2_r[1],e2_r[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - #============================================ - if True: - # prepare diagonal images - # top right image - e1_tr = e1 + offset_y + offset_x - e2_tr = e2 + offset_y + offset_x - # bottom right image - e1_br = e1 - offset_y + offset_x - e2_br = e2 - offset_y + offset_x - # top left image - e1_tl = e1 - offset_x + offset_y - e2_tl = e2 - offset_x + offset_y - # bottom left image - e1_bl = e1 - offset_x - offset_y - e2_bl = e2 - offset_x - offset_y - # top-right image - #========================================== - # draw the outlines initialized in black - glColor3f(0.0, 0.0, 0.0) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_LINE_SMOOTH) - glLineWidth(8.0) - - # draw wireframe for back facing polygons and cull front-facing ones - glPolygonMode(GL_BACK, GL_FILL) - glEnable(GL_CULL_FACE) - glCullFace(GL_FRONT) - glDepthFunc(GL_LEQUAL) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_tr[0],e1_tr[1],e1_tr[2]) - gluSphere(self.quad, r, 8, 8) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_tr[0],e2_tr[1],e2_tr[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - glDepthFunc(GL_LESS) - glDisable(GL_CULL_FACE) - glPolygonMode(GL_FRONT, GL_FILL) - glDisable(GL_LINE_SMOOTH) - glDisable(GL_BLEND) - - glColor3fv(cellcol2) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_tr[0],e1_tr[1],e1_tr[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - #glScalef(1.25,1.0,1.0) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l*1.25, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_tr[0],e2_tr[1],e2_tr[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - #============================================ - - # bottom right image - #========================================== - # draw the outlines initialized in black - glColor3f(0.0, 0.0, 0.0) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_LINE_SMOOTH) - glLineWidth(8.0) - - # draw wireframe for back facing polygons and cull front-facing ones - glPolygonMode(GL_BACK, GL_FILL) - glEnable(GL_CULL_FACE) - glCullFace(GL_FRONT) - glDepthFunc(GL_LEQUAL) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_br[0],e1_br[1],e1_br[2]) - gluSphere(self.quad, r, 8, 8) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_br[0],e2_br[1],e2_br[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - glDepthFunc(GL_LESS) - glDisable(GL_CULL_FACE) - glPolygonMode(GL_FRONT, GL_FILL) - glDisable(GL_LINE_SMOOTH) - glDisable(GL_BLEND) - - glColor3fv(cellcol2) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_br[0],e1_br[1],e1_br[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - #glScalef(1.25,1.0,1.0) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l*1.25, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_br[0],e2_br[1],e2_br[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - #============================================ - - # top left image - #========================================== - # draw the outlines initialized in black - glColor3f(0.0, 0.0, 0.0) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_LINE_SMOOTH) - glLineWidth(8.0) - - # draw wireframe for back facing polygons and cull front-facing ones - glPolygonMode(GL_BACK, GL_FILL) - glEnable(GL_CULL_FACE) - glCullFace(GL_FRONT) - glDepthFunc(GL_LEQUAL) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_tl[0],e1_tl[1],e1_tl[2]) - gluSphere(self.quad, r, 8, 8) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_tl[0],e2_tl[1],e2_tl[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - glDepthFunc(GL_LESS) - glDisable(GL_CULL_FACE) - glPolygonMode(GL_FRONT, GL_FILL) - glDisable(GL_LINE_SMOOTH) - glDisable(GL_BLEND) - - glColor3fv(cellcol2) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_tl[0],e1_tl[1],e1_tl[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - #glScalef(1.25,1.0,1.0) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l*1.25, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_tl[0],e2_tl[1],e2_tl[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - #============================================ - # bottom left image - #========================================== - # draw the outlines initialized in black - glColor3f(0.0, 0.0, 0.0) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_LINE_SMOOTH) - glLineWidth(8.0) - - # draw wireframe for back facing polygons and cull front-facing ones - glPolygonMode(GL_BACK, GL_FILL) - glEnable(GL_CULL_FACE) - glCullFace(GL_FRONT) - glDepthFunc(GL_LEQUAL) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_bl[0],e1_bl[1],e1_bl[2]) - gluSphere(self.quad, r, 8, 8) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_bl[0],e2_bl[1],e2_bl[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - glDepthFunc(GL_LESS) - glDisable(GL_CULL_FACE) - glPolygonMode(GL_FRONT, GL_FILL) - glDisable(GL_LINE_SMOOTH) - glDisable(GL_BLEND) - - glColor3fv(cellcol2) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1_bl[0],e1_bl[1],e1_bl[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - #glScalef(1.25,1.0,1.0) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l*1.25, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2_bl[0],e2_bl[1],e2_bl[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - #============================================ - #glColor3f(68.0 / 256, 81.0 / 256, 44.0 / 256) - #glLineWidth(2) - #glBegin(GL_LINES) - #glVertex3f(e1[0], e1[1], e1[2]) - #glVertex3f(e2[0], e2[1], e2[2]) - #glEnd() - # - #glColor3f(1.0, 1.0, 0.0) - #glPointSize(3) - #glBegin(GL_POINTS) - #glVertex3f(e1[0], e1[1], e1[2]) - #glVertex3f(e2[0], e2[1], e2[2]) - #glEnd() - + def __init__(self, sim, properties=None, scales = None): + self.ncells_list = 0 + self.ncells_names_list = 0 + self.dlist = None + self.dlist_names = None + self.cellcol = [1, 1, 1] + self.sim = sim + self.quad = gluNewQuadric() + self.properties = properties + self.scales = scales + + def init_gl(self): + pass + + def build_list(self, cells): + if self.dlist: + glDeleteLists(self.dlist, 1) + index = glGenLists(1) + glNewList(index, GL_COMPILE) + self.render_cells() + textString = 'CellModeller4 Development Version' #self.render_text(position, textString, 40) + position = numpy.array([-40.0,30.0,0.0]) + glEndList() + self.dlist = index + + def build_list_names(self, cells): + if self.dlist_names: + glDeleteLists(self.dlist_names, 1) + index = glGenLists(1) + glNewList(index, GL_COMPILE) + self.render_cell_names() + glEndList() + self.dlist_names = index + + def render_gl(self, selection=None): + cells = self.sim.cellStates.values() + states = self.sim.cellStates.items() + # FIXED ============================================================================= + # Before, the renderer would only draw cells when the number of cells changed. + # Now it draws them whenever render_gl is called (by paintGL in PyGLCMViewer.py) + + names = False + if not names: + self.build_list(cells) + self.ncells_list = len(cells) + glCallList(self.dlist) + else: + # added to try and render cell ids + self.build_list_names(cells) + self.ncells_names_list = len(cells) + glCallList(self.dlist_names) + + #if len(cells)!=self.ncells_list: + # self.build_list(cells) + # self.ncells_list = len(cells) + #==================================================================================== + #glCallList(self.dlist) + #glCallList(self.dlist_names) + #for cell in cells: self.render_cell(cell, selection) + + + def renderNames_gl(self, selection=None): + cells = self.sim.cellStates.values() + if len(cells)!=self.ncells_names_list: + self.build_list_names(cells) + self.ncells_names_list = len(cells) + glCallList(self.dlist_names) + #for cell in cells: self.render_cell_name(cell, selection) + + + def render_cell_names(self): + # glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + for cell in self.sim.cellStates.values(): + l = cell.length + r = cell.radius + + (e1,e2) = cell.ends + ae1 = numpy.array(e1) + ae2 = numpy.array(e2) + zaxis = numpy.array([0,0,1]) + caxis = numpy.array(cell.dir) #(ae2-ae1)/l + rotaxis = numpy.cross(caxis, zaxis) + rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) + + cid = cell.id + glPushName(cid) + + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glPopName() + + glEnable(GL_LIGHTING) + + #def render_text(self, position, textString, fontSize): + # pygame.font.init() + # font = pygame.font.Font (None, fontSize) + # textSurface = font.render(textString, True, (0,0,0,225), (255,255,255,255)) + # textData = pygame.image.tostring(textSurface, "RGBA", True) + # glRasterPos3d(*position) + # glDrawPixels(textSurface.get_width(), textSurface.get_height(), GL_RGBA, GL_UNSIGNED_BYTE, textData) + # #glClear(GL_DEPTH_BUFFER_BIT) + + def render_cells(self, selection=None): + #glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + cells = self.sim.cellStates.values() + for cell in cells: + l = cell.length + #r = cell.radius*2.0 + r = cell.radius + + (e1,e2) = cell.ends + + L_x = self.sim.phys.max_x_coord - self.sim.phys.min_x_coord + L_y = self.sim.phys.max_y_coord - self.sim.phys.min_y_coord + offset_x = numpy.array([L_x,0.0,0.0]) + offset_y = numpy.array([0.0,L_y,0.0]) + + # top image + e1_t = e1 + offset_y + e2_t = e2 + offset_y + # bottom image + e1_b = e1 - offset_y + e2_b = e2 - offset_y + # left image + e1_l = e1 - offset_x + e2_l = e2 - offset_x + # right image + e1_r = e1 + offset_x + e2_r = e2 + offset_x + + zaxis = numpy.array([0,0,1]) + caxis = numpy.array(cell.dir) #(ae2-ae1)/l + rotaxis = numpy.cross(caxis, zaxis) + rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) + + cid = cell.id + #======================================================== Adding cell labels + cidx = cell.idx + #if self.sim.render_labels: + if False: + self.render_text(0.5*(e1+e2), str(cidx), 24) + #======================================================== + if selection==cid: + cellcol = [1,0,0] + else: + cellcol = cell.color #self.cellcol #[random.uniform(0,1), random.uniform(0,1), random.uniform(0,1)] + if self.properties: + cellcol = [] + for p in self.properties: + if hasattr(cell,p): + cellcol.append(getattr(cell,p)) + else: + cellcol.append(0) + for i in range(3): + cellcol[i] *= self.scales[i] + cellcol[i] = min(1,cellcol[i]) + + # image cells are grey + cellcol2 = numpy.array([0.9,0.9,0.9]) + + # main image + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + # FIXME ========================================= + #() + #================================================ + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + # draw contact points + #========================================================= + if hasattr(cells[0], 'contacts'): + #========================================================= used to always be false but it won't work anyway - see below + glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + for cell in cells: + contacts = cell.contacts # this won't work because cellStates no longer have a contacts attribute + glBegin(GL_LINES) + for ct in contacts: + glColor3fv(ct[6:9]) + glVertex3fv(ct[0:3]) + glVertex3fv(ct[3:6]) + glEnd() + glBegin(GL_POINTS) + for ct in contacts: + glColor3fv(ct[6:9]) + glVertex3fv(ct[0:3]) + glEnd() + glEnable(GL_DEPTH_TEST) + glEnable(GL_LIGHTING) + + # top image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_t[0],e1_t[1],e1_t[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_t[0],e2_t[1],e2_t[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_t[0],e1_t[1],e1_t[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_t[0],e2_t[1],e2_t[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + + # bottom image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_b[0],e1_b[1],e1_b[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_b[0],e2_b[1],e2_b[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_b[0],e1_b[1],e1_b[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_b[0],e2_b[1],e2_b[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + + # left image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_l[0],e1_l[1],e1_l[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_l[0],e2_l[1],e2_l[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_l[0],e1_l[1],e1_l[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_l[0],e2_l[1],e2_l[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + # right image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_r[0],e1_r[1],e1_r[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_r[0],e2_r[1],e2_r[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_r[0],e1_r[1],e1_r[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_r[0],e2_r[1],e2_r[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + if True: + # prepare diagonal images + # top right image + e1_tr = e1 + offset_y + offset_x + e2_tr = e2 + offset_y + offset_x + # bottom right image + e1_br = e1 - offset_y + offset_x + e2_br = e2 - offset_y + offset_x + # top left image + e1_tl = e1 - offset_x + offset_y + e2_tl = e2 - offset_x + offset_y + # bottom left image + e1_bl = e1 - offset_x - offset_y + e2_bl = e2 - offset_x - offset_y + # top-right image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_tr[0],e1_tr[1],e1_tr[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_tr[0],e2_tr[1],e2_tr[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_tr[0],e1_tr[1],e1_tr[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_tr[0],e2_tr[1],e2_tr[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + + # bottom right image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_br[0],e1_br[1],e1_br[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_br[0],e2_br[1],e2_br[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_br[0],e1_br[1],e1_br[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_br[0],e2_br[1],e2_br[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + + # top left image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_tl[0],e1_tl[1],e1_tl[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_tl[0],e2_tl[1],e2_tl[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_tl[0],e1_tl[1],e1_tl[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_tl[0],e2_tl[1],e2_tl[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + # bottom left image + #========================================== + # draw the outlines initialized in black + glColor3f(0.0, 0.0, 0.0) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_bl[0],e1_bl[1],e1_bl[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_bl[0],e2_bl[1],e2_bl[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol2) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1_bl[0],e1_bl[1],e1_bl[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2_bl[0],e2_bl[1],e2_bl[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + #============================================ + #glColor3f(68.0 / 256, 81.0 / 256, 44.0 / 256) + #glLineWidth(2) + #glBegin(GL_LINES) + #glVertex3f(e1[0], e1[1], e1[2]) + #glVertex3f(e2[0], e2[1], e2[2]) + #glEnd() + # + #glColor3f(1.0, 1.0, 0.0) + #glPointSize(3) + #glBegin(GL_POINTS) + #glVertex3f(e1[0], e1[1], e1[2]) + #glVertex3f(e2[0], e2[1], e2[2]) + #glEnd() + class GLWillsMeshRenderer: - def __init__(self,sim): - self.sim = sim - - def render_gl(self, selection=None): # is it necessary to have this method? YES - self.render_mesh() - - def render_mesh(self): - - # choose mesh color - glColor3f(0,1,0) # green - - # get domain info - min_x = self.sim.phys.min_x_coord - min_y = self.sim.phys.min_y_coord - max_x = self.sim.phys.max_x_coord - max_y = self.sim.phys.max_y_coord - nx = self.sim.phys.grid_x_max - self.sim.phys.grid_x_min - ny = self.sim.phys.grid_y_max - self.sim.phys.grid_y_min - z_offset = -0.1 - h = self.sim.phys.grid_spacing - glLineWidth(2) - - # render lines in x direction - for i in range(0,ny+1): - glBegin( GL_LINES ) - glVertex3f(min_x, min_y + i*h, z_offset) - glVertex3f(max_x, min_y + i*h, z_offset) - glEnd( ) - - # render lines in y direction - for j in range(0,nx+1): - glBegin( GL_LINES ) - glVertex3f(min_x + j*h, min_y, z_offset) - glVertex3f(min_x + j*h, max_y, z_offset) - glEnd( ) - - - - + def __init__(self,sim): + self.sim = sim + + def render_gl(self, selection=None): # is it necessary to have this method? YES + self.render_mesh() + + def render_mesh(self): + + # choose mesh color + glColor3f(0,1,0) # green + + # get domain info + min_x = self.sim.phys.min_x_coord + min_y = self.sim.phys.min_y_coord + max_x = self.sim.phys.max_x_coord + max_y = self.sim.phys.max_y_coord + nx = self.sim.phys.grid_x_max - self.sim.phys.grid_x_min + ny = self.sim.phys.grid_y_max - self.sim.phys.grid_y_min + z_offset = -0.1 + h = self.sim.phys.grid_spacing + glLineWidth(2) + + # render lines in x direction + for i in range(0,ny+1): + glBegin( GL_LINES ) + glVertex3f(min_x, min_y + i*h, z_offset) + glVertex3f(max_x, min_y + i*h, z_offset) + glEnd( ) + + # render lines in y direction + for j in range(0,nx+1): + glBegin( GL_LINES ) + glVertex3f(min_x + j*h, min_y, z_offset) + glVertex3f(min_x + j*h, max_y, z_offset) + glEnd( ) + + + + class GLStaticMeshRenderer: def __init__(self, mesh, regul): self.mesh = mesh diff --git a/Examples/ex1b_simpleGrowthRoundCell.py b/Examples/ex1b_simpleGrowthRoundCell.py index 1bfd8c99..e65b7c8b 100644 --- a/Examples/ex1b_simpleGrowthRoundCell.py +++ b/Examples/ex1b_simpleGrowthRoundCell.py @@ -8,7 +8,7 @@ def setup(sim): # Set biophysics, signalling, and regulation models - biophys = CLBacterium(sim, jitter_z=False) + biophys = CLBacterium(sim, jitter_z=True) # use this file for reg too regul = ModuleRegulator(sim, sim.moduleName) diff --git a/Examples/ex5_colonySector.py b/Examples/ex5_colonySector.py index 2764c528..0ef79705 100644 --- a/Examples/ex5_colonySector.py +++ b/Examples/ex5_colonySector.py @@ -26,12 +26,12 @@ def setup(sim): def init(cell): cell.targetVol = 3.5 + random.uniform(0.0,0.5) cell.growthRate = 1.0 - cell.n_a = 3 - cell.n_b = 3 + cell.n_a = 10 + cell.n_b = 10 def update(cells): for (id, cell) in cells.items(): - cell.color = [0.1, cell.n_a/3.0, cell.n_b/3.0] + cell.color = [0.1, cell.n_a/20.0, cell.n_b/20.0] if cell.volume > cell.targetVol: cell.divideFlag = True @@ -44,15 +44,15 @@ def divide(parent, d1, d2): d1.n_b = 0 d2.n_a = 0 d2.n_b = 0 - for p in plasmids[:6]: + for p in plasmids[:20]: if p == 0: d1.n_a +=1 else: d1.n_b +=1 - for p in plasmids[6:12]: + for p in plasmids[20:40]: if p == 0: d2.n_a +=1 else: d2.n_b +=1 - assert parent.n_a + parent.n_b == 6 - assert d1.n_a + d1.n_b == 6 - assert d2.n_a + d2.n_b == 6 + assert parent.n_a + parent.n_b == 20 + assert d1.n_a + d1.n_b == 20 + assert d2.n_a + d2.n_b == 20 assert parent.n_a*2 == d1.n_a+d2.n_a assert parent.n_b*2 == d1.n_b+d2.n_b assert parent.n_a > 0 or (d1.n_a == 0 and d2.n_a == 0) diff --git a/Scripts/CellModellerGUI.py b/Scripts/CellModellerGUI.py index f074440f..3c057574 100644 --- a/Scripts/CellModellerGUI.py +++ b/Scripts/CellModellerGUI.py @@ -26,6 +26,8 @@ ui.show() ui.raise_() cmv = ui.PyGLCMViewer +pix_ratio = qapp.devicePixelRatio() +cmv.setPixelRatio(pix_ratio) # Load a model if specified if len(sys.argv) > 1: cmv.loadModelFile(sys.argv[1]) From 3fe8065b8488be3640ab854aba0620cdd4cc3b17 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Sun, 19 Apr 2020 15:15:22 -0400 Subject: [PATCH 07/26] Tidy up display of cell properties in GUI --- CellModeller/GUI/PyGLCMViewer.py | 14 ++++++++++---- Scripts/CellModellerGUI.py | 4 ++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CellModeller/GUI/PyGLCMViewer.py b/CellModeller/GUI/PyGLCMViewer.py index 0dcd00ba..f16597a0 100644 --- a/CellModeller/GUI/PyGLCMViewer.py +++ b/CellModeller/GUI/PyGLCMViewer.py @@ -15,6 +15,7 @@ import pickle import pyopencl as cl import importlib +import numpy as np class PyGLCMViewer(PyGLWidget): @@ -222,13 +223,18 @@ def updateSelectedCell(self): cid = self.selectedName txt = '' if cid in states: - txt += 'Selected Cell (id = %d)\n---\n'%(cid) + txt += 'Selected Cell (id = %d)
'%(cid) s = states[cid] for (name,val) in list(s.__dict__.items()): if name not in CellState.excludeAttr: - txt += name + ': ' - txt += str(val) - txt += '\n' + txt += '' + name + ':\t' + if type(val) in [float, np.float32, np.float64]: + txt += '%.3g'%val + elif type(val) in [list, tuple, np.array]: + txt += ', '.join(['%.3g'%v for v in val]) + else: + txt += str(val) + txt += '
' self.selectedCell.emit(txt) self.updateGL() diff --git a/Scripts/CellModellerGUI.py b/Scripts/CellModellerGUI.py index 3c057574..23f3b699 100644 --- a/Scripts/CellModellerGUI.py +++ b/Scripts/CellModellerGUI.py @@ -8,6 +8,7 @@ from PyQt5.QtWidgets import QApplication from PyQt5 import uic +from PyQt5.QtCore import * import CellModeller.GUI.Renderers from CellModeller import Simulator @@ -28,6 +29,9 @@ cmv = ui.PyGLCMViewer pix_ratio = qapp.devicePixelRatio() cmv.setPixelRatio(pix_ratio) +label = ui.label +label.setTextFormat(Qt.RichText) +label.setAlignment(Qt.AlignJustify) # Load a model if specified if len(sys.argv) > 1: cmv.loadModelFile(sys.argv[1]) From 5f9fae3d76d02b647d4099986d3957c9c7a5191d Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Sun, 31 May 2020 00:02:07 -0400 Subject: [PATCH 08/26] Added spherical constraints, added sphere renderer for simple cells, various other tweeks, and python3 conversion of scripts --- .../Biophysics/BacterialModels/CLBacterium.cl | 89 ++++- .../Biophysics/BacterialModels/CLBacterium.py | 50 +++ CellModeller/GUI/Renderers.py | 357 ++++++++++++------ CellModeller/Simulator.py | 20 +- Examples/ex5_colonySector.py | 107 ++++-- Scripts/Draw2DPDF.py | 16 +- Scripts/LengthHistogram.py | 4 +- Scripts/batch.py | 6 +- Scripts/batchFile.py | 6 +- Scripts/contactGraph.py | 6 +- Scripts/multi_batch.py | 4 +- Scripts/printTiming.py | 2 +- Scripts/video.sh | 4 +- 13 files changed, 491 insertions(+), 180 deletions(-) diff --git a/CellModeller/Biophysics/BacterialModels/CLBacterium.cl b/CellModeller/Biophysics/BacterialModels/CLBacterium.cl index 36e243b9..f322540b 100644 --- a/CellModeller/Biophysics/BacterialModels/CLBacterium.cl +++ b/CellModeller/Biophysics/BacterialModels/CLBacterium.cl @@ -298,6 +298,93 @@ float pt_to_plane_dist(float4 v, float4 n, float4 p) return dot((p-v), n); } +// intest distance from a point p to a sphere at point v +// with radius r +float pt_to_sphere_dist(float4 v, float rad, float4 p) +{ + return length(p - v) - rad; +} + +__kernel void find_sphere_contacts(const int max_cells, + const int max_contacts, + const int n_spheres, + __global const float4* sphere_pts, + __global const float* sphere_coeffs, + __global const float* sphere_rads, + __global const float4* centers, + __global const float4* dirs, + __global const float* lens, + __global const float* rads, + __global int* n_cts, + __global int* frs, + __global int* tos, + __global float* dists, + __global float4* pts, + __global float4* norms, + __global float* reldists, + __global float* stiff) +{ + int i = get_global_id(0); + + // collision count + int k = n_cts[i]; //keep existing contacts + + float4 end1 = centers[i] - 0.5f*lens[i]*dirs[i]; // 'left' end of the cell + float4 end2 = centers[i] + 0.5f*lens[i]*dirs[i]; // 'right' end of the cell + + for (int n = 0; n < n_spheres; n++) { // loop through all spheres + int to1 = -2*n - 1; // 'to' if left end has contact with sphere n + int to2 = to1 - 1; // 'to' if right end has contact with sphere n + + float dist1 = pt_to_sphere_dist(sphere_pts[n], sphere_rads[n], end1)-rads[i]; + float dist2 = pt_to_sphere_dist(sphere_pts[n], sphere_rads[n], end2)-rads[i]; + + // check for old contacts with this sphere + int cti1 = -1; + int cti2 = -1; + for (int m = i*max_contacts; m < i*max_contacts+n_cts[i]; m++) { + if (tos[m] == to1) cti1 = m; + else if (tos[m] == to2) cti2 = m; + } + + bool two_pts = ((cti1 >= 0) || (dist1<0.f) ) && ( (cti2 >= 0) || (dist2<0.f) ); + float stiffness = two_pts*ISQRT2 + (!two_pts)*1.0; + + // if we're in contact, or we were in contact, recompute + if ((cti1 >= 0) || (dist1<0.f) ){ + // need to make a new contact + if (cti1 < 0) { + cti1 = i*max_contacts+k; + k++; + } + + frs[cti1] = i; + tos[cti1] = to1; + dists[cti1] = dist1; + pts[cti1] = end1; // FIXME: not really the right point + norms[cti1] = normalize(-end1 + sphere_pts[n]); + reldists[cti1] = stiffness*sphere_coeffs[n]*dist1; + stiff[cti1] = stiffness*sphere_coeffs[n]; + } + + if ( (cti2 >= 0) || (dist2<0.f) ){ + if (cti2 < 0) { + cti2 = i*max_contacts+k; + k++; + } + + frs[cti2] = i; + tos[cti2] = to2; + dists[cti2] = dist2; + pts[cti2] = end2; + norms[cti2] = normalize(-end2 + sphere_pts[n]); + reldists[cti2] = stiffness*sphere_coeffs[n]*dist2; + stiff[cti2] = stiffness*sphere_coeffs[n]; + } + } + n_cts[i] = k; +} + __kernel void find_plane_contacts(const int max_cells, const int max_contacts, @@ -676,7 +763,7 @@ __kernel void build_matrix(const int max_contacts, int b = tos[i]; - // plane contacts have no to_ent, and have negative indices + // plane and sphere contacts have no to_ent, and have negative indices if (b < 0) { to_ents[i] = 0.f; return; diff --git a/CellModeller/Biophysics/BacterialModels/CLBacterium.py b/CellModeller/Biophysics/BacterialModels/CLBacterium.py index 68afd810..2b801b46 100644 --- a/CellModeller/Biophysics/BacterialModels/CLBacterium.py +++ b/CellModeller/Biophysics/BacterialModels/CLBacterium.py @@ -22,6 +22,7 @@ def __init__(self, simulator, max_cells=10000, max_contacts=24, max_planes=4, + max_spheres=4, max_sqs=192**2, grid_spacing=5.0, muA=1.0, @@ -49,6 +50,7 @@ def __init__(self, simulator, self.max_cells = max_cells self.max_contacts = max_contacts self.max_planes = max_planes + self.max_spheres = max_spheres self.max_sqs = max_sqs self.grid_spacing = grid_spacing self.muA = muA @@ -62,6 +64,7 @@ def __init__(self, simulator, self.n_cells = 0 self.n_cts = 0 self.n_planes = 0 + self.n_spheres = 0 self.next_id = 0 @@ -88,6 +91,7 @@ def reset(self): self.n_cells=0 self.n_cts=0 self.n_planes=0 + self.n_spheres=0 def setRegulator(self, regulator): self.regulator = regulator @@ -133,6 +137,14 @@ def addPlane(self, pt, norm, coeff): self.plane_coeffs[pidx] = coeff self.set_planes() + def addSphere(self, pt, rad, coeff): + sidx = self.n_spheres + self.n_spheres += 1 + self.sphere_pts[sidx] = tuple(pt)+(0,) + self.sphere_rads[sidx] = rad + self.sphere_coeffs[sidx] = coeff + self.set_spheres() + def hasNeighbours(self): return False @@ -233,6 +245,15 @@ def init_data(self): self.plane_coeffs = numpy.zeros(plane_geom, numpy.float32) self.plane_coeffs_dev = cl_array.zeros(self.queue, plane_geom, numpy.float32) + # constraint spheres + sphere_geom = (self.max_spheres,) + self.sphere_pts = numpy.zeros(sphere_geom, vec.float4) + self.sphere_pts_dev = cl_array.zeros(self.queue, sphere_geom, vec.float4) + self.sphere_rads = numpy.zeros(sphere_geom, numpy.float32) + self.sphere_rads_dev = cl_array.zeros(self.queue, sphere_geom, numpy.float32) + self.sphere_coeffs = numpy.zeros(sphere_geom, numpy.float32) + self.sphere_coeffs_dev = cl_array.zeros(self.queue, sphere_geom, numpy.float32) + # contact data ct_geom = (self.max_cells, self.max_contacts) self.ct_frs = numpy.zeros(ct_geom, numpy.int32) @@ -427,6 +448,13 @@ def set_planes(self): self.plane_coeffs_dev[0:self.n_planes].set(self.plane_coeffs[0:self.n_planes]) + def set_spheres(self): + """Copy sphere pts and coeffs to the device from local.""" + self.sphere_pts_dev[0:self.n_spheres].set(self.sphere_pts[0:self.n_spheres]) + self.sphere_rads_dev[0:self.n_spheres].set(self.sphere_rads[0:self.n_spheres]) + self.sphere_coeffs_dev[0:self.n_spheres].set(self.sphere_coeffs[0:self.n_spheres]) + + def get_cts(self): """Copy contact froms, tos, dists, pts, and norms from the device.""" self.ct_frs[0:self.n_cts] = self.ct_frs_dev[0:self.n_cts].get() @@ -758,6 +786,28 @@ def find_contacts(self, predict=True): self.ct_reldists_dev.data, self.ct_stiff_dev.data).wait() + self.program.find_sphere_contacts(self.queue, + (self.n_cells,), + None, + numpy.int32(self.max_cells), + numpy.int32(self.max_contacts), + numpy.int32(self.n_spheres), + self.sphere_pts_dev.data, + self.sphere_coeffs_dev.data, + self.sphere_rads_dev.data, + centers.data, + dirs.data, + lens.data, + self.cell_rads_dev.data, + self.cell_n_cts_dev.data, + self.ct_frs_dev.data, + self.ct_tos_dev.data, + self.ct_dists_dev.data, + self.ct_pts_dev.data, + self.ct_norms_dev.data, + self.ct_reldists_dev.data, + self.ct_stiff_dev.data).wait() + self.program.find_contacts(self.queue, (self.n_cells,), None, diff --git a/CellModeller/GUI/Renderers.py b/CellModeller/GUI/Renderers.py index 7bb02441..eb2a66ad 100644 --- a/CellModeller/GUI/Renderers.py +++ b/CellModeller/GUI/Renderers.py @@ -7,6 +7,113 @@ #import pygame # helper module for text rendering - turned off to see if it suppresses segfaults #from pyopencl.array import vec +class GLSphereRenderer: + def __init__(self, sim, properties=None, scales = None): + self.ncells_list = 0 + self.ncells_names_list = 0 + self.dlist = None + self.dlist_names = None + self.cellcol = [1, 1, 1] + self.sim = sim + self.quad = gluNewQuadric() + self.properties = properties + self.scales = scales + + def init_gl(self): + pass + + def build_list(self, cells): + if self.dlist: + glDeleteLists(self.dlist, 1) + index = glGenLists(1) + glNewList(index, GL_COMPILE) + self.render_cells() + glEndList() + self.dlist = index + + def build_list_names(self, cells): + if self.dlist_names: + glDeleteLists(self.dlist_names, 1) + index = glGenLists(1) + glNewList(index, GL_COMPILE) + self.render_cell_names() + glEndList() + self.dlist_names = index + + def render_gl(self, selection=None): + cells = self.sim.cellStates.values() + states = self.sim.cellStates.items() + # FIXED ============================================================================= + # Before, the renderer would only draw cells when the number of cells changed. + # Now it draws them whenever render_gl is called (by paintGL in PyGLCMViewer.py) + #if len(cells)!=self.ncells_list or len(cells)<500: + # self.build_list(cells) + # self.ncells_list = len(cells) + + #if len(cells)!=self.ncells_list: + # self.build_list(cells) + # self.ncells_list = len(cells) + #==================================================================================== + #glCallList(self.dlist) + self.render_cells(selection=selection) + + + def renderNames_gl(self, selection=None): + #cells = self.sim.cellStates.values() + #if len(cells)!=self.ncells_names_list or len(cells)<500: + # self.build_list_names(cells) + # self.ncells_names_list = len(cells) + #glCallList(self.dlist_names) + #for cell in cells: self.render_cell_name(cell, selection) + self.render_cell_names() + + def render_cell_names(self): + # glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + for cell in self.sim.cellStates.values(): + l = cell.length + p = cell.pos + + cid = cell.id + glPushName(cid) + + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(p[0],p[1],p[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + glPopName() + + glEnable(GL_LIGHTING) + + def render_cell(self, cell, selection): + r = cell.radius + p = cell.pos + cid = cell.id + if selection==cid: + cellcol = [1,0,0] + else: + cellcol = cell.color + + glColor3fv(cellcol) + + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(p[0],p[1],p[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + def render_cells(self, selection=None): + + # PLACEHOLDER + + #glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + cells = self.sim.cellStates.values() + for cell in cells: + self.render_cell(cell, selection) + class GLGridRenderer: def __init__(self, sig, integ, rng=None): self.sig = sig @@ -254,26 +361,26 @@ def render_gl(self, selection=None): # FIXED ============================================================================= # Before, the renderer would only draw cells when the number of cells changed. # Now it draws them whenever render_gl is called (by paintGL in PyGLCMViewer.py) - if len(cells)!=self.ncells_list or len(cells)<500: - self.build_list(cells) - self.ncells_list = len(cells) + #if len(cells)!=self.ncells_list or len(cells)<500: + # self.build_list(cells) + # self.ncells_list = len(cells) #if len(cells)!=self.ncells_list: # self.build_list(cells) # self.ncells_list = len(cells) #==================================================================================== - glCallList(self.dlist) - #for cell in cells: self.render_cell(cell, selection) + #glCallList(self.dlist) + self.render_cells(selection=selection) def renderNames_gl(self, selection=None): - cells = self.sim.cellStates.values() - if len(cells)!=self.ncells_names_list or len(cells)<500: - self.build_list_names(cells) - self.ncells_names_list = len(cells) - glCallList(self.dlist_names) + #cells = self.sim.cellStates.values() + #if len(cells)!=self.ncells_names_list or len(cells)<500: + # self.build_list_names(cells) + # self.ncells_names_list = len(cells) + #glCallList(self.dlist_names) #for cell in cells: self.render_cell_name(cell, selection) - + self.render_cell_names() def render_cell_names(self): # glDisable(GL_DEPTH_TEST) @@ -325,6 +432,121 @@ def render_cell_names(self): glEnable(GL_LIGHTING) + def render_cell(self, cell, selection): + l = cell.length + #r = cell.radius*2.0 + r = cell.radius + + (e1,e2) = cell.ends + ae1 = numpy.array(e1) + ae2 = numpy.array(e2) + zaxis = numpy.array([0,0,1]) + caxis = numpy.array(cell.dir) #(ae2-ae1)/l + rotaxis = numpy.cross(caxis, zaxis) + rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) + + cid = cell.id + cidx = cell.idx + if False: + self.render_text(0.5*(e1+e2), str(cidx), 24) + + if selection==cid: + linecol = [1,0,0] + else: + linecol = [0,0,0] + cellcol = cell.color + if self.properties: + cellcol = [] + for p in self.properties: + if hasattr(cell,p): + cellcol.append(getattr(cell,p)) + else: + cellcol.append(0) + for i in range(3): + cellcol[i] *= self.scales[i] + cellcol[i] = min(1,cellcol[i]) + + # draw the outlines antialiased in black + glColor3fv(linecol) + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + glLineWidth(8.0) + # draw wireframe for back facing polygons and cull front-facing ones + glPolygonMode(GL_BACK, GL_FILL) + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + glDepthFunc(GL_LEQUAL) + + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + gluSphere(self.quad, r, 8, 8) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + + glDepthFunc(GL_LESS) + glDisable(GL_CULL_FACE) + glPolygonMode(GL_FRONT, GL_FILL) + glDisable(GL_LINE_SMOOTH) + glDisable(GL_BLEND) + + glColor3fv(cellcol) + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + glTranslatef(e1[0],e1[1],e1[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + #glScalef(1.25,1.0,1.0) + glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) + gluCylinder(self.quad, r, r , l*1.25, 8, 1) + glPopMatrix() + glPushMatrix() + glTranslatef(e2[0],e2[1],e2[2]) + glScalef(0.8,0.8,0.8) + gluSphere(self.quad, r, 8, 8) + glPopMatrix() + + #glColor3f(68.0 / 256, 81.0 / 256, 44.0 / 256) + #glLineWidth(2) + #glBegin(GL_LINES) + #glVertex3f(e1[0], e1[1], e1[2]) + #glVertex3f(e2[0], e2[1], e2[2]) + #glEnd() + # + #glColor3f(1.0, 1.0, 0.0) + #glPointSize(3) + #glBegin(GL_POINTS) + #glVertex3f(e1[0], e1[1], e1[2]) + #glVertex3f(e2[0], e2[1], e2[2]) + #glEnd() + + # draw contact points + if False: #hasattr(cells[0], 'contacts'): + glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + for cell in cells: + contacts = cell.contacts + glBegin(GL_LINES) + for ct in contacts: + glColor3fv(ct[6:9]) + glVertex3fv(ct[0:3]) + glVertex3fv(ct[3:6]) + glEnd() + glBegin(GL_POINTS) + for ct in contacts: + glColor3fv(ct[6:9]) + glVertex3fv(ct[0:3]) + glEnd() + glEnable(GL_DEPTH_TEST) + glEnable(GL_LIGHTING) + def render_cells(self, selection=None): # PLACEHOLDER @@ -333,118 +555,7 @@ def render_cells(self, selection=None): glDisable(GL_LIGHTING) cells = self.sim.cellStates.values() for cell in cells: - l = cell.length - #r = cell.radius*2.0 - r = cell.radius - - (e1,e2) = cell.ends - ae1 = numpy.array(e1) - ae2 = numpy.array(e2) - zaxis = numpy.array([0,0,1]) - caxis = numpy.array(cell.dir) #(ae2-ae1)/l - rotaxis = numpy.cross(caxis, zaxis) - rotangle = numpy.arccos(numpy.dot(caxis,zaxis)) - - cid = cell.id - cidx = cell.idx - if False: - self.render_text(0.5*(e1+e2), str(cidx), 24) - - if selection==cid: - cellcol = [1,0,0] - else: - cellcol = cell.color #self.cellcol #[random.uniform(0,1), random.uniform(0,1), random.uniform(0,1)] - if self.properties: - cellcol = [] - for p in self.properties: - if hasattr(cell,p): - cellcol.append(getattr(cell,p)) - else: - cellcol.append(0) - for i in range(3): - cellcol[i] *= self.scales[i] - cellcol[i] = min(1,cellcol[i]) - - # draw the outlines antialiased in black - glColor3f(0.0, 0.0, 0.0) - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glEnable(GL_LINE_SMOOTH) - glLineWidth(8.0) - # draw wireframe for back facing polygons and cull front-facing ones - glPolygonMode(GL_BACK, GL_FILL) - glEnable(GL_CULL_FACE) - glCullFace(GL_FRONT) - glDepthFunc(GL_LEQUAL) - - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1[0],e1[1],e1[2]) - gluSphere(self.quad, r, 8, 8) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2[0],e2[1],e2[2]) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - - glDepthFunc(GL_LESS) - glDisable(GL_CULL_FACE) - glPolygonMode(GL_FRONT, GL_FILL) - glDisable(GL_LINE_SMOOTH) - glDisable(GL_BLEND) - - glColor3fv(cellcol) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glTranslatef(e1[0],e1[1],e1[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - #glScalef(1.25,1.0,1.0) - glRotatef(-rotangle*180.0/numpy.pi, rotaxis[0], rotaxis[1], rotaxis[2]) - gluCylinder(self.quad, r, r , l*1.25, 8, 1) - glPopMatrix() - glPushMatrix() - glTranslatef(e2[0],e2[1],e2[2]) - glScalef(0.8,0.8,0.8) - gluSphere(self.quad, r, 8, 8) - glPopMatrix() - - #glColor3f(68.0 / 256, 81.0 / 256, 44.0 / 256) - #glLineWidth(2) - #glBegin(GL_LINES) - #glVertex3f(e1[0], e1[1], e1[2]) - #glVertex3f(e2[0], e2[1], e2[2]) - #glEnd() - # - #glColor3f(1.0, 1.0, 0.0) - #glPointSize(3) - #glBegin(GL_POINTS) - #glVertex3f(e1[0], e1[1], e1[2]) - #glVertex3f(e2[0], e2[1], e2[2]) - #glEnd() - - # draw contact points - if False: #hasattr(cells[0], 'contacts'): - glDisable(GL_DEPTH_TEST) - glDisable(GL_LIGHTING) - for cell in cells: - contacts = cell.contacts - glBegin(GL_LINES) - for ct in contacts: - glColor3fv(ct[6:9]) - glVertex3fv(ct[0:3]) - glVertex3fv(ct[3:6]) - glEnd() - glBegin(GL_POINTS) - for ct in contacts: - glColor3fv(ct[6:9]) - glVertex3fv(ct[0:3]) - glEnd() - glEnable(GL_DEPTH_TEST) - glEnable(GL_LIGHTING) + self.render_cell(cell, selection) class GLBacteriumRendererWithPeriodicImages: def __init__(self, sim, properties=None, scales = None): diff --git a/CellModeller/Simulator.py b/CellModeller/Simulator.py index a14a1e56..a7284605 100644 --- a/CellModeller/Simulator.py +++ b/CellModeller/Simulator.py @@ -392,16 +392,16 @@ def writePickle(self, csv=False): data['lineage'] = self.lineage data['moduleStr'] = self.moduleOutput data['moduleName'] = self.moduleName - if self.integ: - print("Writing new pickle format") - data['specData'] = self.integ.levels - data['sigGrid'] = self.integ.signalLevel - data['sigGridOrig'] = self.sig.gridOrig - data['sigGridDim'] = self.sig.gridDim - data['sigGridSize'] = self.sig.gridSize - if self.sig: - data['sigData'] = self.integ.cellSigLevels - data['sigGrid'] = self.integ.signalLevel + #if self.integ: + # print("Writing new pickle format") + # data['specData'] = self.integ.levels + # data['sigGrid'] = self.integ.signalLevel + # data['sigGridOrig'] = self.sig.gridOrig + # data['sigGridDim'] = self.sig.gridDim + # data['sigGridSize'] = self.sig.gridSize + #if self.sig: + # data['sigData'] = self.integ.cellSigLevels + # data['sigGrid'] = self.integ.signalLevel pickle.dump(data, outfile, protocol=-1) #output csv file with cell pos,dir,len - sig? diff --git a/Examples/ex5_colonySector.py b/Examples/ex5_colonySector.py index 0ef79705..ecfee7c4 100644 --- a/Examples/ex5_colonySector.py +++ b/Examples/ex5_colonySector.py @@ -1,9 +1,15 @@ import random from CellModeller.Regulation.ModuleRegulator import ModuleRegulator from CellModeller.Biophysics.BacterialModels.CLBacterium import CLBacterium -import numpy +import numpy as np import math +l = 60. +K = 10. +n = 1.5 +Kn = K**n +_b_ = 10. +_N0_ = 10. def setup(sim): # Set biophysics, signalling, and regulation models @@ -26,34 +32,91 @@ def setup(sim): def init(cell): cell.targetVol = 3.5 + random.uniform(0.0,0.5) cell.growthRate = 1.0 - cell.n_a = 10 - cell.n_b = 10 + cell.N0 = 0 + cell.p1, cell.p2, cell.p3 = 0,0,0 + +def repressilator_step(cell, dt): + t = 0 + #for i in range(10000): + while t cell.targetVol: cell.divideFlag = True + repressilator_step(cell, 0.01*60) def divide(parent, d1, d2): d1.targetVol = 3.5 + random.uniform(0.0,0.5) d2.targetVol = 3.5 + random.uniform(0.0,0.5) - plasmids = [0]*parent.n_a*2 + [1]*parent.n_b*2 - random.shuffle(plasmids) - d1.n_a = 0 - d1.n_b = 0 - d2.n_a = 0 - d2.n_b = 0 - for p in plasmids[:20]: - if p == 0: d1.n_a +=1 - else: d1.n_b +=1 - for p in plasmids[20:40]: - if p == 0: d2.n_a +=1 - else: d2.n_b +=1 - assert parent.n_a + parent.n_b == 20 - assert d1.n_a + d1.n_b == 20 - assert d2.n_a + d2.n_b == 20 - assert parent.n_a*2 == d1.n_a+d2.n_a - assert parent.n_b*2 == d1.n_b+d2.n_b - assert parent.n_a > 0 or (d1.n_a == 0 and d2.n_a == 0) - assert parent.n_b > 0 or (d1.n_b == 0 and d2.n_b == 0) + + # Binomial separation of plasmids and proteins + d1.N0 = np.random.binomial(parent.N0, 0.5) + d2.N0 = parent.N0 - d1.N0 + d1.p1 = np.random.binomial(parent.p1, 0.5) + d2.p1 = parent.p1 - d1.p1 + d1.p2 = np.random.binomial(parent.p2, 0.5) + d2.p2 = parent.p2 - d1.p2 + d1.p3 = np.random.binomial(parent.p3, 0.5) + d2.p3 = parent.p3 - d1.p3 diff --git a/Scripts/Draw2DPDF.py b/Scripts/Draw2DPDF.py index 81b61a95..928a7cb9 100644 --- a/Scripts/Draw2DPDF.py +++ b/Scripts/Draw2DPDF.py @@ -140,7 +140,7 @@ def computeBox(self): mnx = -20 mxy = 20 mny = -20 - for (id,s) in self.states.items(): + for (id,s) in list(self.states.items()): pos = s.pos l = s.length # add/sub length to keep cell in frame mxx = max(mxx,pos[0]+l) @@ -155,7 +155,7 @@ def computeBox(self): def importPickle(fname): if fname[-7:]=='.pickle': - print('Importing CellModeller pickle file: %s'%fname) + print(('Importing CellModeller pickle file: %s'%fname)) data = pickle.load(open(fname, 'rb')) # Check for old-style pickle that is tuple, @@ -182,19 +182,19 @@ def main(): # e.g. outline color, page size, etc. # # For now, put these options into variables here: - bg_color = Color(1.0,1.0,1.0,alpha=1.0) + bg_color = Color(0,0,0,alpha=1.0) # For now just assume a list of files infns = sys.argv[1:] for infn in infns: # File names if infn[-7:]!='.pickle': - print('Ignoring file %s, because its not a pickle...'%(infn)) + print(('Ignoring file %s, because its not a pickle...'%(infn))) continue - outfn = string.replace(infn, '.pickle', '.pdf') + outfn = infn.replace('.pickle', '.pdf') outfn = os.path.basename(outfn) # Put output in this dir - print('Processing %s to generate %s'%(infn,outfn)) + print(('Processing %s to generate %s'%(infn,outfn))) # Import data data = importPickle(infn) @@ -211,14 +211,14 @@ def main(): '''(w,h) = pdf.computeBox() sqrt2 = math.sqrt(2) world = (w/sqrt2,h/sqrt2)''' - world = (250,250) + world = (100,100) # Page setup page = (20,20) center = (0,0) # Render pdf - print('Rendering PDF output to %s'%outfn) + print(('Rendering PDF output to %s'%outfn)) pdf.draw_frame(outfn, world, page, center) if __name__ == "__main__": diff --git a/Scripts/LengthHistogram.py b/Scripts/LengthHistogram.py index 643182e2..7253bcfd 100644 --- a/Scripts/LengthHistogram.py +++ b/Scripts/LengthHistogram.py @@ -20,7 +20,7 @@ def lengthHist(pickle, bins, file=False): cs = data['cellStates'] it = iter(cs) n = len(cs) - print('Number of cells = '+str(n)) + print(('Number of cells = '+str(n))) lens = [] r = [] for it in cs: @@ -44,7 +44,7 @@ def dirLengthHist(dir,bins,file=False): number = f[5:-7] if file: fout = open('LengthData'+number+'.csv') - print('step number = ', number) + print(('step number = ', number)) n, lens = lengthHist(dir + f,bins,file) if file: fout.close() diff --git a/Scripts/batch.py b/Scripts/batch.py index 40729604..4df6969d 100644 --- a/Scripts/batch.py +++ b/Scripts/batch.py @@ -6,7 +6,7 @@ from CellModeller.Simulator import Simulator -max_cells = 10000 +max_cells = 5000 cell_buffer = 256 def simulate(modfilename, platform, device, steps=50): @@ -33,14 +33,14 @@ def main(): platforms = cl.get_platforms() print("Select OpenCL platform:") for i in range(len(platforms)): - print('press '+str(i)+' for '+str(platforms[i])) + print(('press '+str(i)+' for '+str(platforms[i]))) platnum = int(eval(input('Platform Number: '))) # Device devices = platforms[platnum].get_devices() print("Select OpenCL device:") for i in range(len(devices)): - print('press '+str(i)+' for '+str(devices[i])) + print(('press '+str(i)+' for '+str(devices[i]))) devnum = int(eval(input('Device Number: '))) else: platnum = int(sys.argv[2]) diff --git a/Scripts/batchFile.py b/Scripts/batchFile.py index 01f87c68..50472678 100644 --- a/Scripts/batchFile.py +++ b/Scripts/batchFile.py @@ -10,7 +10,7 @@ sys.path.append('./') -print(os.getcwd()) +print((os.getcwd())) import CellModeller.AdaptiveSimulator @@ -39,14 +39,14 @@ try: os.mkdir(pickleDir) except OSError: - print(pickleDir, 'exists') + print((pickleDir, 'exists')) pickleSetDir = os.path.join(pickleDir, mod_name) try: os.mkdir(pickleSetDir) except: - print(pickleSetDir, 'exists') + print((pickleSetDir, 'exists')) folderName = time.strftime('%Y%m%d-%H%M%S', time.localtime()) pickleFileRoot = os.path.join(pickleSetDir, folderName) diff --git a/Scripts/contactGraph.py b/Scripts/contactGraph.py index 7c7cb17d..2c38ccbd 100644 --- a/Scripts/contactGraph.py +++ b/Scripts/contactGraph.py @@ -110,7 +110,7 @@ def get_current_contacts(G, data): n = len(cs) oname = fname.replace('.pickle','_graph.pdf') -print("num_cells = "+str(n)) +print(("num_cells = "+str(n))) cell_type={} pos_dict={} @@ -120,9 +120,9 @@ def get_current_contacts(G, data): get_current_contacts(G, data) -print("num_contacts = " + str(networkx.number_of_edges(G))) +print(("num_contacts = " + str(networkx.number_of_edges(G)))) degrees = list(G.degree().values()) -print("mean degree = " + str(np.mean(degrees))) +print(("mean degree = " + str(np.mean(degrees)))) if list(networkx.get_edge_attributes(G,'color').items()): edges,ecolor = list(zip(*list(networkx.get_edge_attributes(G,'color').items()))) diff --git a/Scripts/multi_batch.py b/Scripts/multi_batch.py index b1058302..781ca5aa 100644 --- a/Scripts/multi_batch.py +++ b/Scripts/multi_batch.py @@ -33,14 +33,14 @@ def main(): platforms = cl.get_platforms() print("Select OpenCL platform:") for i in range(len(platforms)): - print('press '+str(i)+' for '+str(platforms[i])) + print(('press '+str(i)+' for '+str(platforms[i]))) platnum = int(eval(input('Platform Number: '))) # Device devices = platforms[platnum].get_devices() print("Select OpenCL device:") for i in range(len(devices)): - print('press '+str(i)+' for '+str(devices[i])) + print(('press '+str(i)+' for '+str(devices[i]))) devnum = int(eval(input('Device Number: '))) else: platnum = int(sys.argv[2]) diff --git a/Scripts/printTiming.py b/Scripts/printTiming.py index 8cdd128b..f6f3996c 100644 --- a/Scripts/printTiming.py +++ b/Scripts/printTiming.py @@ -14,5 +14,5 @@ (cs,lin) = pickle.load(open(ff,'r')) n = len(cs) t = os.path.getmtime(ff) - print("%i\t%f"%(n,t)) + print(("%i\t%f"%(n,t))) diff --git a/Scripts/video.sh b/Scripts/video.sh index 2d7073ec..b48c0b4c 100755 --- a/Scripts/video.sh +++ b/Scripts/video.sh @@ -7,7 +7,7 @@ # Run Draw2DPDF to generate pdf files for f in $( ls *.pickle ); do echo Processing: $f - $CMPATH/bin/cmpython $CMPATH/Scripts/Draw2DPDF.py $f + python $HOME/Code/CellModeller/Scripts/Draw2DPDF.py $f done # Convert and resize etc. pdf files into jpegs @@ -21,4 +21,4 @@ for f in $( ls *.pdf ); do done # Run ffmpeg to generate video file -ffmpeg -framerate 7 -i step-%04d0.png -vf scale=1920:1080 -r 24 $1 +ffmpeg -framerate 7 -i %*.png -vf scale=1920:1080 -r 24 $1 From e8d2927d582435e9886642cc189c94a8c0a6443c Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Tue, 9 Jun 2020 16:14:32 -0400 Subject: [PATCH 09/26] Tweaks to Draw2DPDF --- Scripts/Draw2DPDF.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/Draw2DPDF.py b/Scripts/Draw2DPDF.py index 928a7cb9..de1864e6 100644 --- a/Scripts/Draw2DPDF.py +++ b/Scripts/Draw2DPDF.py @@ -173,7 +173,7 @@ def calc_cell_colors(self, state): # Generate Color objects from cellState, fill=stroke (r,g,b) = state.color # Return value is tuple of colors, (fill, stroke) - fcol = Color(r,g,b,alpha=1.0) + fcol = Color(r*2,g*2,b*2,alpha=1.0) scol = Color(r*0.5,g*0.5,b*0.5,alpha=1.0) return [fcol,scol] @@ -211,7 +211,7 @@ def main(): '''(w,h) = pdf.computeBox() sqrt2 = math.sqrt(2) world = (w/sqrt2,h/sqrt2)''' - world = (100,100) + world = (200,200) # Page setup page = (20,20) From b519fdde84a098866a967ef5ebc3dc00f33cfd79 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Wed, 10 Jun 2020 08:58:51 -0400 Subject: [PATCH 10/26] Roughly working version solving directly for deltax instead of deltap. Problem with rotational motion, inertia tensor incorrect? --- .../Biophysics/BacterialModels/CLBacterium.cl | 120 +++++++++++++----- .../Biophysics/BacterialModels/CLBacterium.py | 18 ++- Examples/ex1_simpleGrowth.py | 27 ++-- 3 files changed, 117 insertions(+), 48 deletions(-) diff --git a/CellModeller/Biophysics/BacterialModels/CLBacterium.cl b/CellModeller/Biophysics/BacterialModels/CLBacterium.cl index f322540b..8b36e1a9 100644 --- a/CellModeller/Biophysics/BacterialModels/CLBacterium.cl +++ b/CellModeller/Biophysics/BacterialModels/CLBacterium.cl @@ -122,6 +122,45 @@ void print_matrix(float4* m) { */ } +void cyl_inertia_tensor(float muA, float l, float4 axis, float4 res[]) { + // first find the inv inertia tensor for a capsule along the x axis + float diag = (muA*l*l*l) / 12.f; + + // now find the matrix that transforms from the x-axis to the axis + float4 x_axis = {1.f, 0.f, 0.f, 0.f}; + float4 y_axis = {0.f, 1.f, 0.f, 0.f}; + float4 z_axis = {0.f, 0.f, 1.f, 0.f}; + float rot_ang = acos(dot(x_axis, axis)); + + float4 y_prime = y_axis; + float4 z_prime = z_axis; + + if (rot_ang > EPSILON) { + y_prime = rot(z_prime, rot_ang, y_axis); + z_prime = normalize(cross(x_axis, axis)); + } + + float4 M[4]; + M[0] = axis; + M[1] = y_prime; + M[2] = z_prime; + M[3] = 0.f; + + float4 MT[4]; + transpose(M, MT); + + float4 I[4]; + I[0][0] = 0.f; + I[1][1] = diag; + I[2][2] = diag; + I[3][3] = 0.f; + + // M^T(I)M + float4 IM[4]; + matmulmat(I, M, IM); + matmulmat(MT, IM, res); +} + void cyl_inv_inertia_tensor(float muA, float l, float4 axis, float4 res[]) { // first find the inv inertia tensor for a capsule along the x axis float diag = 12.f/(muA*l*l*l); @@ -723,8 +762,6 @@ __kernel void collect_tos(const int max_cells, __kernel void build_matrix(const int max_contacts, - const float muA, - const float gamma, __global const float4* centers, __global const float4* dirs, __global const float* lens, @@ -749,16 +786,15 @@ __kernel void build_matrix(const int max_contacts, float4 r_a = pts[i]-centers[a]; float8 fr_ent = 0.f; - float4 Ia[4]; - cyl_inv_inertia_tensor(muA, lens[a]+2.f*rads[a], dirs[a], Ia); float4 nxr_a = 0.f; nxr_a = cross(norms[i], r_a); - fr_ent.s012 = norms[i].s012/(muA*(lens[a]+2.f*rads[a])); - fr_ent.s3 = -dot(nxr_a, Ia[0]); - fr_ent.s4 = -dot(nxr_a, Ia[1]); - fr_ent.s5 = -dot(nxr_a, Ia[2]); - fr_ent.s6 = (1.f/gamma) * dot(dirs[a], r_a) * dot(dirs[a], norms[i])/(lens[a]+2.f*rads[a]); + fr_ent.s012 = norms[i].s012; + fr_ent.s345 = -nxr_a.s012; + //fr_ent.s3 = -dot(nxr_a, Ia[0]); + //fr_ent.s4 = -dot(nxr_a, Ia[1]); + //fr_ent.s5 = -dot(nxr_a, Ia[2]); + fr_ent.s6 = dot(dirs[a], r_a) * dot(dirs[a], norms[i])/(lens[a]+2.f*rads[a]); fr_ents[i] = fr_ent * stiff[i]; int b = tos[i]; @@ -772,26 +808,25 @@ __kernel void build_matrix(const int max_contacts, float4 r_b = pts[i]-centers[b]; float8 to_ent = 0.f; - float4 Ib[4]; - cyl_inv_inertia_tensor(muA, lens[b]+2.f*rads[b], dirs[b], Ib); float4 nxr_b = 0.f; nxr_b = cross(norms[i], r_b); - to_ent.s012 = norms[i].s012/(muA*(lens[b]+2.f*rads[b])); - to_ent.s3 = -dot(nxr_b, Ib[0]); - to_ent.s4 = -dot(nxr_b, Ib[1]); - to_ent.s5 = -dot(nxr_b, Ib[2]); - to_ent.s6 = (1.f/gamma) * dot(dirs[b], r_b) * dot(dirs[b], norms[i])/(lens[b]+2.f*rads[b]); + to_ent.s012 = norms[i].s012; + to_ent.s345 = -nxr_b.s012; + //to_ent.s3 = -dot(nxr_b, Ib[0]); + //to_ent.s4 = -dot(nxr_b, Ib[1]); + //to_ent.s5 = -dot(nxr_b, Ib[2]); + to_ent.s6 = dot(dirs[b], r_b) * dot(dirs[b], norms[i])/(lens[b]+2.f*rads[b]); to_ents[i] = to_ent * stiff[i]; } -__kernel void calculate_Mx(const int max_contacts, +__kernel void calculate_Bx(const int max_contacts, __global const int* frs, __global const int* tos, __global const float8* fr_ents, __global const float8* to_ents, __global const float8* deltap, - __global float* Mx) + __global float* Bx) { int id = get_global_id(0); int ct = get_global_id(1); @@ -803,34 +838,61 @@ __kernel void calculate_Mx(const int max_contacts, //my machine can't dot float8s... float res0123 = dot(fr_ents[i].s0123, deltap[a].s0123) - dot(to_ents_i.s0123, deltap[b].s0123); float res4567 = dot(fr_ents[i].s4567, deltap[a].s4567) - dot(to_ents_i.s4567, deltap[b].s4567); - Mx[i] = res0123 + res4567; + Bx[i] = res0123 + res4567; } -__kernel void calculate_MTMx(const int max_contacts, +__kernel void calculate_BTBx(const int max_contacts, __global const int* n_cts, __global const int* n_cell_tos, __global const int* cell_tos, __global const float8* fr_ents, __global const float8* to_ents, - __global const float* Mx, - __global float8* MTMx) + __global const float* Bx, + __global float8* BTBx) { int i = get_global_id(0); int base = i*max_contacts; float8 res = 0.f; for (int k = base; k < base+n_cts[i]; k++) { float8 oldres = res; - res += fr_ents[k]*Mx[k]; + res += fr_ents[k]*Bx[k]; } for (int k = base; k < base+n_cell_tos[i]; k++) { int n = cell_tos[k]; if (n < 0) continue; - res -= to_ents[n]*Mx[n]; + res -= to_ents[n]*Bx[n]; } - MTMx[i] = res; + BTBx[i] = res; +} + +__kernel void calculate_Mx(const float muA, + const float gamma, + __global const float4* dirs, + __global const float* lens, + __global const float* rads, + __global const float8* x, + __global float8* Mx) +{ + int i = get_global_id(0); + + float8 xi = x[i]; + float8 v = 0.f; + v.s012 = xi.s012*(muA*(lens[i]+2.f*rads[i])); + + float4 I[4]; + cyl_inertia_tensor(muA, lens[i]+2.f*rads[i], dirs[i], I); + float4 L = 0.f; + L.s012 = xi.s345; + float4 w = matmul(I, L); + v.s345 = w.s012; + + v.s6 = xi.s6*gamma; + + Mx[i] = v; } + __kernel void calculate_Minv_x(const float muA, const float gamma, __global const float4* dirs, @@ -943,7 +1005,7 @@ __kernel void add_impulse(const float muA, float4 dplin = 0.f; dplin.s012 = deltap_i.s012; - dcenters[i] += dplin/(muA*(lens[i]+2.f*rads[i])); + dcenters[i] += dplin; // FIXME: should probably store these so we don't recompute them float4 Iinv[4]; @@ -956,11 +1018,11 @@ __kernel void add_impulse(const float muA, { dpang *= ANG_LIMIT/dpangmag; } - dangs[i] += dpang; + dangs[i] += dL; //dpang; float dplen = deltap_i.s6; - //dlens[i] += max(0.f, target_dlens[i] + dplen/gamma); - dlens[i] = max(0.f, dlens[i]+dplen/gamma); + //dlens[i] += max(0.f, target_dlens[i] + dplen); + dlens[i] = max(0.f, dlens[i]+dplen); } diff --git a/CellModeller/Biophysics/BacterialModels/CLBacterium.py b/CellModeller/Biophysics/BacterialModels/CLBacterium.py index 2b801b46..2418a13f 100644 --- a/CellModeller/Biophysics/BacterialModels/CLBacterium.py +++ b/CellModeller/Biophysics/BacterialModels/CLBacterium.py @@ -296,8 +296,8 @@ def init_data(self): self.deltap_dev = cl_array.zeros(self.queue, cell_geom, vec.float8) self.Mx = numpy.zeros(mat_geom, numpy.float32) self.Mx_dev = cl_array.zeros(self.queue, mat_geom, numpy.float32) - self.MTMx = numpy.zeros(cell_geom, vec.float8) - self.MTMx_dev = cl_array.zeros(self.queue, cell_geom, vec.float8) + self.BTBx = numpy.zeros(cell_geom, vec.float8) + self.BTBx_dev = cl_array.zeros(self.queue, cell_geom, vec.float8) self.Minvx_dev = cl_array.zeros(self.queue, cell_geom, vec.float8) # CGS intermediates @@ -883,8 +883,6 @@ def build_matrix(self): (self.n_cells, self.max_contacts), None, numpy.int32(self.max_contacts), - numpy.float32(self.muA), - numpy.float32(self.gamma), self.pred_cell_centers_dev.data, self.pred_cell_dirs_dev.data, self.pred_cell_lens_dev.data, @@ -901,7 +899,7 @@ def build_matrix(self): def calculate_Ax(self, Ax, x, dt): - self.program.calculate_Mx(self.queue, + self.program.calculate_Bx(self.queue, (self.n_cells, self.max_contacts), None, numpy.int32(self.max_contacts), @@ -911,7 +909,7 @@ def calculate_Ax(self, Ax, x, dt): self.to_ents_dev.data, x.data, self.Mx_dev.data).wait() - self.program.calculate_MTMx(self.queue, + self.program.calculate_BTBx(self.queue, (self.n_cells,), None, numpy.int32(self.max_contacts), @@ -926,7 +924,7 @@ def calculate_Ax(self, Ax, x, dt): #self.vaddkx(Ax, numpy.float32(0.01), Ax, x) # Energy mimizing regularization - self.program.calculate_Minv_x(self.queue, + self.program.calculate_Mx(self.queue, (self.n_cells,), None, numpy.float32(self.muA), @@ -952,7 +950,7 @@ def CGSSolve(self, dt, substep=False): self.vclearf(self.rhs_dev[0:self.n_cells]) # put M^T n^Tv_rel in rhs (b) - self.program.calculate_MTMx(self.queue, + self.program.calculate_BTBx(self.queue, (self.n_cells,), None, numpy.int32(self.max_contacts), @@ -965,8 +963,8 @@ def CGSSolve(self, dt, substep=False): self.rhs_dev.data).wait() # res = b-Ax - self.calculate_Ax(self.MTMx_dev, self.deltap_dev, dt) - self.vsub(self.res_dev[0:self.n_cells], self.rhs_dev[0:self.n_cells], self.MTMx_dev[0:self.n_cells]) + self.calculate_Ax(self.BTBx_dev, self.deltap_dev, dt) + self.vsub(self.res_dev[0:self.n_cells], self.rhs_dev[0:self.n_cells], self.BTBx_dev[0:self.n_cells]) # p = res cl.enqueue_copy(self.queue, self.p_dev[0:self.n_cells].data, self.res_dev[0:self.n_cells].data) diff --git a/Examples/ex1_simpleGrowth.py b/Examples/ex1_simpleGrowth.py index 6be5c195..3e5fe8e6 100644 --- a/Examples/ex1_simpleGrowth.py +++ b/Examples/ex1_simpleGrowth.py @@ -9,7 +9,7 @@ def setup(sim): # Set biophysics, signalling, and regulation models - biophys = CLBacterium(sim, jitter_z=False) + biophys = CLBacterium(sim, jitter_z=False, max_cells=100000, reg_param=0.01, gamma=10.) # use this file for reg too regul = ModuleRegulator(sim, sim.moduleName) @@ -20,14 +20,14 @@ def setup(sim): sim.addCell(cellType=0, pos=(0,0,0), dir=(1,0,0)) # Add some objects to draw the models - if sim.is_gui: - from CellModeller.GUI import Renderers - therenderer = Renderers.GLBacteriumRenderer(sim) - sim.addRenderer(therenderer) - else: - print("Running in batch mode: no display will be output") - - sim.pickleSteps = 10 + #if sim.is_gui: + from CellModeller.GUI import Renderers + therenderer = Renderers.GLBacteriumRenderer(sim) + sim.addRenderer(therenderer) + #else: + # print("Running in batch mode: no display will be output") + + sim.pickleSteps = 100 sim.saveOutput = True def init(cell): @@ -43,6 +43,15 @@ def update(cells): if cell.volume > cell.targetVol: cell.divideFlag = True + gr = cell.strainRate/0.05 + cgr = gr - 0.5 + # Return value is tuple of colors, (fill, stroke) + #if cgr>0: + # cell.color = [1, 1-cgr*2, 1-cgr*2] + #else: + # cell.color = [1+cgr*2, 1+cgr*2, 1] + + def divide(parent, d1, d2): # Specify target cell size that triggers cell division d1.targetVol = 3.5 + random.uniform(0.0,0.5) From 58ceeea44d453e2c0be58fc44610b1eb12c1f800 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Wed, 10 Jun 2020 23:27:26 -0400 Subject: [PATCH 11/26] Use correct matrix transform for drag matrix M --- .../Biophysics/BacterialModels/CLBacterium.cl | 28 +++++++++++++------ .../Biophysics/BacterialModels/CLBacterium.py | 27 +++++++++++------- Examples/ex1_simpleGrowth.py | 2 +- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/CellModeller/Biophysics/BacterialModels/CLBacterium.cl b/CellModeller/Biophysics/BacterialModels/CLBacterium.cl index 8b36e1a9..48bd86d5 100644 --- a/CellModeller/Biophysics/BacterialModels/CLBacterium.cl +++ b/CellModeller/Biophysics/BacterialModels/CLBacterium.cl @@ -875,19 +875,26 @@ __kernel void calculate_Mx(const float muA, __global float8* Mx) { int i = get_global_id(0); + float l = lens[i] + 2.f * rads[i]; float8 xi = x[i]; float8 v = 0.f; - v.s012 = xi.s012*(muA*(lens[i]+2.f*rads[i])); + v.s012 = xi.s012 * muA * l; float4 I[4]; - cyl_inertia_tensor(muA, lens[i]+2.f*rads[i], dirs[i], I); + cyl_inertia_tensor(muA, l, dirs[i], I); float4 L = 0.f; L.s012 = xi.s345; float4 w = matmul(I, L); v.s345 = w.s012; - v.s6 = xi.s6*gamma; + //float4 w = 0.f; + //w.s012 = xi.s345; + //float4 a = dirs[i]; + //float4 vv = (w - a*dot(a,w)) * muA * l*l*l / 12.f; + //v.s345 = vv.s012; + + v.s6 = xi.s6 * gamma; Mx[i] = v; } @@ -1008,17 +1015,20 @@ __kernel void add_impulse(const float muA, dcenters[i] += dplin; // FIXME: should probably store these so we don't recompute them - float4 Iinv[4]; - cyl_inv_inertia_tensor(muA, len_i+2.f*rad_i, dir_i, Iinv); - float4 dL = 0.f; - dL.s012 = deltap_i.s345; - float4 dpang = matmul(Iinv, dL); + //float4 Iinv[4]; + //cyl_inv_inertia_tensor(muA, len_i+2.f*rad_i, dir_i, Iinv); + //float4 dL = 0.f; + //dL.s012 = deltap_i.s345; + //float4 dpang = matmul(Iinv, dL); + + float4 dpang = 0.f; + dpang.s012 = deltap_i.s345; float dpangmag = length(dpang); if (dpangmag>ANG_LIMIT) { dpang *= ANG_LIMIT/dpangmag; } - dangs[i] += dL; //dpang; + dangs[i] += dpang; float dplen = deltap_i.s6; //dlens[i] += max(0.f, target_dlens[i] + dplen); diff --git a/CellModeller/Biophysics/BacterialModels/CLBacterium.py b/CellModeller/Biophysics/BacterialModels/CLBacterium.py index 2418a13f..05a8d40d 100644 --- a/CellModeller/Biophysics/BacterialModels/CLBacterium.py +++ b/CellModeller/Biophysics/BacterialModels/CLBacterium.py @@ -21,8 +21,8 @@ def __init__(self, simulator, max_substeps=8, max_cells=10000, max_contacts=24, - max_planes=4, - max_spheres=4, + max_planes=1, + max_spheres=1, max_sqs=192**2, grid_spacing=5.0, muA=1.0, @@ -177,6 +177,9 @@ def init_kernels(self): self.vsubkx = ElementwiseKernel(self.context, "float8 *res, const float k, const float8 *in1, const float8 *in2", "res[i] = in1[i] - k*in2[i]", "vecsubkx") + self.vmulk = ElementwiseKernel(self.context, + "float8 *res, const float k, const float8 *in1", + "res[i] = k*in1[i]", "vecmulk") # cell geometry kernels self.calc_cell_area = ElementwiseKernel(self.context, "float* res, float* r, float* l", @@ -517,7 +520,7 @@ def progress_init(self, dt): self.n_ticks = int(math.ceil(dt/self.dt)) else: self.n_ticks = 1 - #print "n_ticks = %d"%(self.n_ticks) + # print("n_ticks = %d"%(self.n_ticks)) self.actual_dt = dt / float(self.n_ticks) self.progress_initialised = True @@ -604,11 +607,12 @@ def sub_tick(self, dt): self.collect_tos() self.sub_tick_i += 1 + alpha = 10**(self.sub_tick_i) new_cts = self.n_cts - old_n_cts if (new_cts>0 or self.sub_tick_i==0) and self.sub_tick_i Date: Wed, 10 Jun 2020 23:39:19 -0400 Subject: [PATCH 12/26] Replace indexing with swizzle --- CellModeller/Biophysics/BacterialModels/CLBacterium.cl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CellModeller/Biophysics/BacterialModels/CLBacterium.cl b/CellModeller/Biophysics/BacterialModels/CLBacterium.cl index 48bd86d5..19327167 100644 --- a/CellModeller/Biophysics/BacterialModels/CLBacterium.cl +++ b/CellModeller/Biophysics/BacterialModels/CLBacterium.cl @@ -150,10 +150,10 @@ void cyl_inertia_tensor(float muA, float l, float4 axis, float4 res[]) { transpose(M, MT); float4 I[4]; - I[0][0] = 0.f; - I[1][1] = diag; - I[2][2] = diag; - I[3][3] = 0.f; + I[0].s0 = 0.f; + I[1].s1 = diag; + I[2].s2 = diag; + I[3].s3 = 0.f; // M^T(I)M float4 IM[4]; From 3275458ed9ec8e04522347285be51891ace2259b Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Fri, 12 Jun 2020 12:14:52 -0400 Subject: [PATCH 13/26] Change print output from CGSSolve and max_cells in bactch, pdf script updated for correct colors and zoom in --- CellModeller/Biophysics/BacterialModels/CLBacterium.py | 3 ++- Scripts/Draw2DPDF.py | 4 ++-- Scripts/batch.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CellModeller/Biophysics/BacterialModels/CLBacterium.py b/CellModeller/Biophysics/BacterialModels/CLBacterium.py index 05a8d40d..a32f1273 100644 --- a/CellModeller/Biophysics/BacterialModels/CLBacterium.py +++ b/CellModeller/Biophysics/BacterialModels/CLBacterium.py @@ -4,6 +4,7 @@ import pyopencl as cl import pyopencl.array as cl_array from pyopencl.array import vec +from pyopencl.array import max as device_max from pyopencl.elementwise import ElementwiseKernel from pyopencl.reduction import ReductionKernel import random @@ -1025,7 +1026,7 @@ def CGSSolve(self, dt, alpha, substep=False): #print ' ',iter,rsold if self.printing and self.frame_no%10==0: - print('% 5i'%self.frame_no + '% 6i cells % 6i cts % 6i iterations residual = %f' % (self.n_cells, self.n_cts, iter+1, rsnew)) + print('% 5i'%self.frame_no + '% 6i cells % 6i cts % 6i iterations residual = %f' % (self.n_cells, self.n_cts, iter+1, math.sqrt(rsnew/self.n_cells))) return (iter+1, math.sqrt(rsnew/self.n_cells)) diff --git a/Scripts/Draw2DPDF.py b/Scripts/Draw2DPDF.py index de1864e6..91cfb8c3 100644 --- a/Scripts/Draw2DPDF.py +++ b/Scripts/Draw2DPDF.py @@ -173,7 +173,7 @@ def calc_cell_colors(self, state): # Generate Color objects from cellState, fill=stroke (r,g,b) = state.color # Return value is tuple of colors, (fill, stroke) - fcol = Color(r*2,g*2,b*2,alpha=1.0) + fcol = Color(r,g,b,alpha=1.0) scol = Color(r*0.5,g*0.5,b*0.5,alpha=1.0) return [fcol,scol] @@ -211,7 +211,7 @@ def main(): '''(w,h) = pdf.computeBox() sqrt2 = math.sqrt(2) world = (w/sqrt2,h/sqrt2)''' - world = (200,200) + world = (20,20) # Page setup page = (20,20) diff --git a/Scripts/batch.py b/Scripts/batch.py index 4df6969d..c63223a3 100644 --- a/Scripts/batch.py +++ b/Scripts/batch.py @@ -6,7 +6,7 @@ from CellModeller.Simulator import Simulator -max_cells = 5000 +max_cells = 50000 cell_buffer = 256 def simulate(modfilename, platform, device, steps=50): From f9c693b6ea12942b608ce8bd27e9358a4f059e1e Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Fri, 12 Jun 2020 12:25:49 -0400 Subject: [PATCH 14/26] Only remake display list when simulation step has changed --- CellModeller/GUI/Renderers.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/CellModeller/GUI/Renderers.py b/CellModeller/GUI/Renderers.py index eb2a66ad..64e8e5a2 100644 --- a/CellModeller/GUI/Renderers.py +++ b/CellModeller/GUI/Renderers.py @@ -325,6 +325,7 @@ def __init__(self, sim, properties=None, scales = None): self.quad = gluNewQuadric() self.properties = properties self.scales = scales + self.last_rendered_step = -1 def init_gl(self): pass @@ -366,11 +367,13 @@ def render_gl(self, selection=None): # self.ncells_list = len(cells) #if len(cells)!=self.ncells_list: - # self.build_list(cells) - # self.ncells_list = len(cells) + if self.last_rendered_step Date: Sun, 14 Jun 2020 16:18:58 -0400 Subject: [PATCH 15/26] Print correct residual from CGS solver. Change world size for pdf generation. --- CellModeller/Biophysics/BacterialModels/CLBacterium.py | 6 +++++- Scripts/Draw2DPDF.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CellModeller/Biophysics/BacterialModels/CLBacterium.py b/CellModeller/Biophysics/BacterialModels/CLBacterium.py index a32f1273..bb61e08f 100644 --- a/CellModeller/Biophysics/BacterialModels/CLBacterium.py +++ b/CellModeller/Biophysics/BacterialModels/CLBacterium.py @@ -181,6 +181,10 @@ def init_kernels(self): self.vmulk = ElementwiseKernel(self.context, "float8 *res, const float k, const float8 *in1", "res[i] = k*in1[i]", "vecmulk") + self.vnorm = ElementwiseKernel(self.context, + "float8 *res, const float8 *in1", + "res[i] = dot(in1[i], in1[i]", "vecnorm") + # cell geometry kernels self.calc_cell_area = ElementwiseKernel(self.context, "float* res, float* r, float* l", @@ -983,7 +987,7 @@ def CGSSolve(self, dt, alpha, substep=False): if math.sqrt(rsold/self.n_cells) < self.cgs_tol: if self.printing and self.frame_no%10==0: print('% 5i'%self.frame_no + '% 6i cells % 6i cts % 6i iterations residual = %f' % (self.n_cells, - self.n_cts, 0, rsold)) + self.n_cts, 0, math.sqrt(rsold/self.n_cells))) return (0.0, rsold) # iterate diff --git a/Scripts/Draw2DPDF.py b/Scripts/Draw2DPDF.py index 91cfb8c3..fb464df4 100644 --- a/Scripts/Draw2DPDF.py +++ b/Scripts/Draw2DPDF.py @@ -211,7 +211,7 @@ def main(): '''(w,h) = pdf.computeBox() sqrt2 = math.sqrt(2) world = (w/sqrt2,h/sqrt2)''' - world = (20,20) + world = (450,450) # Page setup page = (20,20) From fd9b04ead4a3832ec575b00eba66d46599971197 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Sun, 14 Jun 2020 16:21:38 -0400 Subject: [PATCH 16/26] Remove reg_param to fit with new maths, reg_param=1/gamma --- CellModeller/Biophysics/BacterialModels/CLBacterium.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CellModeller/Biophysics/BacterialModels/CLBacterium.py b/CellModeller/Biophysics/BacterialModels/CLBacterium.py index bb61e08f..b8368a16 100644 --- a/CellModeller/Biophysics/BacterialModels/CLBacterium.py +++ b/CellModeller/Biophysics/BacterialModels/CLBacterium.py @@ -30,7 +30,6 @@ def __init__(self, simulator, gamma=10.0, dt=None, cgs_tol=5e-3, - reg_param=0.1, jitter_z=True, alternate_divisions=False, printing=True, @@ -58,7 +57,6 @@ def __init__(self, simulator, self.gamma = gamma self.dt = dt self.cgs_tol = cgs_tol - self.reg_param = numpy.float32(reg_param) self.max_substeps = max_substeps @@ -947,7 +945,7 @@ def calculate_Ax(self, Ax, x, dt, alpha): #this was altered from dt*reg_param #self.vaddkx(Ax, self.gamma, Ax, self.Mx_dev).wait() #self.vaddkx(Ax, alpha, self.Mx_dev, Ax).wait() - self.vaddkx(Ax, self.reg_param, Ax, self.Mx_dev).wait() + self.vaddkx(Ax, 1/self.gamma, Ax, self.Mx_dev).wait() # 1/math.sqrt(self.n_cells) removed from the reg_param NB #print(self.Minvx_dev) From c4e53f18824e79f26a3021ca23fed52904388a54 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Sun, 14 Jun 2020 16:23:32 -0400 Subject: [PATCH 17/26] Remove reg_param from example models --- Examples/Conjugation.py | 2 +- Examples/ex1_simpleGrowth.py | 2 +- Examples/load.py | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Examples/Conjugation.py b/Examples/Conjugation.py index 0060acd1..b8b9a9a4 100644 --- a/Examples/Conjugation.py +++ b/Examples/Conjugation.py @@ -10,7 +10,7 @@ def setup(sim): # Set biophysics module - biophys = CLBacterium(sim, jitter_z=False, max_cells=50000,gamma=10.0,reg_param=0.1, cgs_tol=1E-5,compNeighbours=True) + biophys = CLBacterium(sim, jitter_z=False, max_cells=50000,gamma=10.0, cgs_tol=1E-5,compNeighbours=True) # Set up regulation module regul = ModuleRegulator(sim, sim.moduleName) diff --git a/Examples/ex1_simpleGrowth.py b/Examples/ex1_simpleGrowth.py index 9632286c..c7ce2cd8 100644 --- a/Examples/ex1_simpleGrowth.py +++ b/Examples/ex1_simpleGrowth.py @@ -9,7 +9,7 @@ def setup(sim): # Set biophysics, signalling, and regulation models - biophys = CLBacterium(sim, jitter_z=False, max_cells=100000, reg_param=0.1, gamma=10., max_substeps=4) + biophys = CLBacterium(sim, jitter_z=False, max_cells=100000, gamma=10., max_substeps=4) # use this file for reg too regul = ModuleRegulator(sim, sim.moduleName) diff --git a/Examples/load.py b/Examples/load.py index b3b037ea..01b7470b 100644 --- a/Examples/load.py +++ b/Examples/load.py @@ -19,7 +19,6 @@ def setup(sim): max_contacts=32, \ max_sqs=128**2, \ jitter_z=False, \ - reg_param=2, \ gamma=10) biophys.addPlane((0,0,-0.5), (0,0,1), 0.2) From 4ca0992f33bd2570ab5734603eeac9d91cec8b75 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Sun, 14 Jun 2020 17:32:18 -0400 Subject: [PATCH 18/26] Add example using sphere constraints --- Examples/sphere_constraints.py | 53 ++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Examples/sphere_constraints.py diff --git a/Examples/sphere_constraints.py b/Examples/sphere_constraints.py new file mode 100644 index 00000000..a32b16cf --- /dev/null +++ b/Examples/sphere_constraints.py @@ -0,0 +1,53 @@ +import random +from CellModeller.Regulation.ModuleRegulator import ModuleRegulator +from CellModeller.Biophysics.BacterialModels.CLBacterium import CLBacterium +from CellModeller.GUI import Renderers +import numpy as np +import math + +max_cells = 50000 + + +def setup(sim): + # Set biophysics, signalling, and regulation models + + #max_sqr + #biophys = CLBacterium(sim, max_cells=max_cells, jitter_z=False, max_sqs=256**2) + biophys = CLBacterium(sim, max_cells=max_cells, jitter_z=False, max_spheres=1, gamma=100.) + + # use this file for reg too + regul = ModuleRegulator(sim) + # Only biophys and regulation + sim.init(biophys, regul, None, None) + + # Specify the initial cell and its location in the simulation + sim.addCell(cellType=0, pos=(0,0,0)) + + biophys.addSphere((40,0,0), 20, 1.0) + + + # Add some objects to draw the models + therenderer = Renderers.GLBacteriumRenderer(sim) + sim.addRenderer(therenderer) + + sim.pickleSteps = 5 + +def init(cell): + # Specify mean and distribution of initial cell size + cell.targetVol = 3.0 + random.uniform(0.0,0.5) + # Specify growth rate of cells + #cell.growthRate = 0.6 + cell.growthRate = 1.0 + cell.color = [0, 1, 0] + +def update(cells): + #Iterate through each cell and flag cells that reach target size for division + for (id, cell) in cells.items(): + if cell.volume > cell.targetVol: + cell.divideFlag = True + +def divide(parent, d1, d2): + # Specify target cell size that triggers cell division + d1.targetVol = 3.0 + random.uniform(0.0,0.5) + d2.targetVol = 3.0 + random.uniform(0.0,0.5) + From fad1415b7159c2a6c2b5cbbef8a8f362a9326bd2 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Sun, 14 Jun 2020 18:05:38 -0400 Subject: [PATCH 19/26] Add normal for sphere constraints, inside or outside sphere --- CellModeller/Biophysics/BacterialModels/CLBacterium.cl | 9 +++++---- CellModeller/Biophysics/BacterialModels/CLBacterium.py | 7 ++++++- Examples/ex1_simpleGrowth.py | 2 +- Examples/sphere_constraints.py | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/CellModeller/Biophysics/BacterialModels/CLBacterium.cl b/CellModeller/Biophysics/BacterialModels/CLBacterium.cl index 19327167..f10e096d 100644 --- a/CellModeller/Biophysics/BacterialModels/CLBacterium.cl +++ b/CellModeller/Biophysics/BacterialModels/CLBacterium.cl @@ -350,6 +350,7 @@ __kernel void find_sphere_contacts(const int max_cells, __global const float4* sphere_pts, __global const float* sphere_coeffs, __global const float* sphere_rads, + __global const float* sphere_norms, __global const float4* centers, __global const float4* dirs, __global const float* lens, @@ -375,8 +376,8 @@ __kernel void find_sphere_contacts(const int max_cells, int to1 = -2*n - 1; // 'to' if left end has contact with sphere n int to2 = to1 - 1; // 'to' if right end has contact with sphere n - float dist1 = pt_to_sphere_dist(sphere_pts[n], sphere_rads[n], end1)-rads[i]; - float dist2 = pt_to_sphere_dist(sphere_pts[n], sphere_rads[n], end2)-rads[i]; + float dist1 = sphere_norms[n] * pt_to_sphere_dist(sphere_pts[n], sphere_rads[n], end1)-rads[i]; + float dist2 = sphere_norms[n] * pt_to_sphere_dist(sphere_pts[n], sphere_rads[n], end2)-rads[i]; // check for old contacts with this sphere int cti1 = -1; @@ -401,7 +402,7 @@ __kernel void find_sphere_contacts(const int max_cells, tos[cti1] = to1; dists[cti1] = dist1; pts[cti1] = end1; // FIXME: not really the right point - norms[cti1] = normalize(-end1 + sphere_pts[n]); + norms[cti1] = sphere_norms[n] * normalize(-end1 + sphere_pts[n]); reldists[cti1] = stiffness*sphere_coeffs[n]*dist1; stiff[cti1] = stiffness*sphere_coeffs[n]; } @@ -416,7 +417,7 @@ __kernel void find_sphere_contacts(const int max_cells, tos[cti2] = to2; dists[cti2] = dist2; pts[cti2] = end2; - norms[cti2] = normalize(-end2 + sphere_pts[n]); + norms[cti2] = sphere_norms[n] * normalize(-end2 + sphere_pts[n]); reldists[cti2] = stiffness*sphere_coeffs[n]*dist2; stiff[cti2] = stiffness*sphere_coeffs[n]; } diff --git a/CellModeller/Biophysics/BacterialModels/CLBacterium.py b/CellModeller/Biophysics/BacterialModels/CLBacterium.py index b8368a16..85d8180d 100644 --- a/CellModeller/Biophysics/BacterialModels/CLBacterium.py +++ b/CellModeller/Biophysics/BacterialModels/CLBacterium.py @@ -136,12 +136,13 @@ def addPlane(self, pt, norm, coeff): self.plane_coeffs[pidx] = coeff self.set_planes() - def addSphere(self, pt, rad, coeff): + def addSphere(self, pt, rad, coeff, norm): sidx = self.n_spheres self.n_spheres += 1 self.sphere_pts[sidx] = tuple(pt)+(0,) self.sphere_rads[sidx] = rad self.sphere_coeffs[sidx] = coeff + self.sphere_norms[sidx] = norm self.set_spheres() def hasNeighbours(self): @@ -259,6 +260,8 @@ def init_data(self): self.sphere_rads_dev = cl_array.zeros(self.queue, sphere_geom, numpy.float32) self.sphere_coeffs = numpy.zeros(sphere_geom, numpy.float32) self.sphere_coeffs_dev = cl_array.zeros(self.queue, sphere_geom, numpy.float32) + self.sphere_norms = numpy.zeros(sphere_geom, numpy.float32) + self.sphere_norms_dev = cl_array.zeros(self.queue, sphere_geom, numpy.float32) # contact data ct_geom = (self.max_cells, self.max_contacts) @@ -459,6 +462,7 @@ def set_spheres(self): self.sphere_pts_dev[0:self.n_spheres].set(self.sphere_pts[0:self.n_spheres]) self.sphere_rads_dev[0:self.n_spheres].set(self.sphere_rads[0:self.n_spheres]) self.sphere_coeffs_dev[0:self.n_spheres].set(self.sphere_coeffs[0:self.n_spheres]) + self.sphere_norms_dev[0:self.n_spheres].set(self.sphere_norms[0:self.n_spheres]) def get_cts(self): @@ -802,6 +806,7 @@ def find_contacts(self, predict=True): self.sphere_pts_dev.data, self.sphere_coeffs_dev.data, self.sphere_rads_dev.data, + self.sphere_norms_dev.data, centers.data, dirs.data, lens.data, diff --git a/Examples/ex1_simpleGrowth.py b/Examples/ex1_simpleGrowth.py index c7ce2cd8..1b845a75 100644 --- a/Examples/ex1_simpleGrowth.py +++ b/Examples/ex1_simpleGrowth.py @@ -9,7 +9,7 @@ def setup(sim): # Set biophysics, signalling, and regulation models - biophys = CLBacterium(sim, jitter_z=False, max_cells=100000, gamma=10., max_substeps=4) + biophys = CLBacterium(sim, jitter_z=False, max_cells=100000, gamma=100.) # use this file for reg too regul = ModuleRegulator(sim, sim.moduleName) diff --git a/Examples/sphere_constraints.py b/Examples/sphere_constraints.py index a32b16cf..2c069e22 100644 --- a/Examples/sphere_constraints.py +++ b/Examples/sphere_constraints.py @@ -23,7 +23,7 @@ def setup(sim): # Specify the initial cell and its location in the simulation sim.addCell(cellType=0, pos=(0,0,0)) - biophys.addSphere((40,0,0), 20, 1.0) + biophys.addSphere((0,0,0), 20, 1.0, -1) # Add some objects to draw the models From b6cf854a06f081b23c5eb4cb62829154370351b0 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Mon, 15 Jun 2020 10:07:11 -0400 Subject: [PATCH 20/26] Update sphere_constraints example, reformat cell details text output --- CellModeller/GUI/PyGLCMViewer.py | 4 ++-- Examples/sphere_constraints.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CellModeller/GUI/PyGLCMViewer.py b/CellModeller/GUI/PyGLCMViewer.py index f16597a0..e6d14f8a 100644 --- a/CellModeller/GUI/PyGLCMViewer.py +++ b/CellModeller/GUI/PyGLCMViewer.py @@ -229,9 +229,9 @@ def updateSelectedCell(self): if name not in CellState.excludeAttr: txt += '' + name + ':\t' if type(val) in [float, np.float32, np.float64]: - txt += '%.3g'%val + txt += '%g'%val elif type(val) in [list, tuple, np.array]: - txt += ', '.join(['%.3g'%v for v in val]) + txt += ', '.join(['%g'%v for v in val]) else: txt += str(val) txt += '
' diff --git a/Examples/sphere_constraints.py b/Examples/sphere_constraints.py index 2c069e22..7d7e2d5f 100644 --- a/Examples/sphere_constraints.py +++ b/Examples/sphere_constraints.py @@ -23,7 +23,7 @@ def setup(sim): # Specify the initial cell and its location in the simulation sim.addCell(cellType=0, pos=(0,0,0)) - biophys.addSphere((0,0,0), 20, 1.0, -1) + biophys.addSphere((0,0,0), 10, 1.0, -1) # Add some objects to draw the models From 035ac66c80ed5f45f2d1ae61e13d3030acae5434 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Tue, 16 Jun 2020 13:14:26 -0400 Subject: [PATCH 21/26] Add time variable to CellStates, updated by simulator --- CellModeller/Simulator.py | 1 + 1 file changed, 1 insertion(+) diff --git a/CellModeller/Simulator.py b/CellModeller/Simulator.py index a7284605..2f652224 100644 --- a/CellModeller/Simulator.py +++ b/CellModeller/Simulator.py @@ -352,6 +352,7 @@ def step(self): self.reg.step(self.dt) states = dict(self.cellStates) for (cid,state) in list(states.items()): + state.time = self.stepNum * self.dt if state.divideFlag: self.divide(state) #neighbours no longer current From 3dfdecd98223ca06e2c9f21deb082123e2e0a9a0 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Wed, 17 Jun 2020 19:27:49 -0400 Subject: [PATCH 22/26] Add alpha as parameter to GridRenderer, change cell line color to white --- CellModeller/GUI/Renderers.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/CellModeller/GUI/Renderers.py b/CellModeller/GUI/Renderers.py index 64e8e5a2..f5dc3128 100644 --- a/CellModeller/GUI/Renderers.py +++ b/CellModeller/GUI/Renderers.py @@ -115,10 +115,11 @@ def render_cells(self, selection=None): self.render_cell(cell, selection) class GLGridRenderer: - def __init__(self, sig, integ, rng=None): + def __init__(self, sig, integ, rng=None, alpha=1.): self.sig = sig self.integ = integ self.rng = rng + self.alpha = alpha self.size = self.sig.gridSize self.dim = self.sig.gridDim[1:] self.len = self.dim[0]*self.dim[1] @@ -162,18 +163,18 @@ def render_gl(self, selection=None): glEnable(GL_TEXTURE_2D) glDisable(GL_LIGHTING) - glDisable(GL_DEPTH_TEST) + #glDisable(GL_DEPTH_TEST) glBindTexture(GL_TEXTURE_2D, self.texture) #Load the Data into the Texture glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, self.texDim, self.texDim, 0, GL_RGB, GL_UNSIGNED_BYTE, self.byteImageData ) # glTexSubImage2Dub( GL_TEXTURE_2D, 0, 0,0, GL_RED, GL_UNSIGNED_BYTE, self.imageData ) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)#GL_LINEAR) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)#GL_LINEAR) + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) #Define some Parameters for this Texture glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA) - glColor4f(1.0,1.0,1.0,0.2) + glColor4f(1.0,1.0,1.0,self.alpha) glBegin(GL_QUADS) glTexCoord2f(0.0, 0.0) glVertex3f(self.orig[0], self.orig[1], 0.0) # Bottom Left Of The Texture and Quad @@ -185,7 +186,7 @@ def render_gl(self, selection=None): glVertex3f(self.orig[0] , self.orig[1]+self.dim[1]*self.size[1], 0.0) glEnd() glEnable(GL_LIGHTING) - glEnable(GL_DEPTH_TEST) + #glEnable(GL_DEPTH_TEST) glDisable(GL_BLEND) glDisable(GL_TEXTURE_2D) @@ -456,7 +457,7 @@ def render_cell(self, cell, selection): if selection==cid: linecol = [1,0,0] else: - linecol = [0,0,0] + linecol = [1,1,1] cellcol = cell.color if self.properties: cellcol = [] From 96d1c6a2e636bfeb13a7767923d434601463cb83 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Wed, 17 Jun 2020 19:28:57 -0400 Subject: [PATCH 23/26] Add z coord to world grid --- CellModeller/GUI/PyGLCMViewer.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CellModeller/GUI/PyGLCMViewer.py b/CellModeller/GUI/PyGLCMViewer.py index e6d14f8a..a53a1b38 100644 --- a/CellModeller/GUI/PyGLCMViewer.py +++ b/CellModeller/GUI/PyGLCMViewer.py @@ -275,16 +275,17 @@ def paintGL(self): #glScalef(s,s,s) # Draw a grid in xy plane + glEnable(GL_DEPTH_TEST) glDisable(GL_LIGHTING) glColor3f(1.0, 1.0, 1.0) glEnable(GL_LINE_SMOOTH) glLineWidth(1.0) glBegin(GL_LINES) for i in range(25): - glVertex(-120, (i-12)*10) - glVertex(120, (i-12)*10) - glVertex((i-12)*10, -120) - glVertex((i-12)*10, 120) + glVertex(-120, (i-12)*10, 0) + glVertex(120, (i-12)*10, 0) + glVertex((i-12)*10, -120, 0) + glVertex((i-12)*10, 120, 0) glEnd() # Draw x,y,z axes From 58fc68cd8d70abee8846d7c344bb36f1ecd4c623 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Wed, 17 Jun 2020 19:29:38 -0400 Subject: [PATCH 24/26] Fix saving of signals and species in pickles --- CellModeller/Simulator.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/CellModeller/Simulator.py b/CellModeller/Simulator.py index 2f652224..0ee2eb3d 100644 --- a/CellModeller/Simulator.py +++ b/CellModeller/Simulator.py @@ -393,16 +393,17 @@ def writePickle(self, csv=False): data['lineage'] = self.lineage data['moduleStr'] = self.moduleOutput data['moduleName'] = self.moduleName - #if self.integ: + if self.integ: # print("Writing new pickle format") - # data['specData'] = self.integ.levels - # data['sigGrid'] = self.integ.signalLevel - # data['sigGridOrig'] = self.sig.gridOrig - # data['sigGridDim'] = self.sig.gridDim - # data['sigGridSize'] = self.sig.gridSize - #if self.sig: - # data['sigData'] = self.integ.cellSigLevels - # data['sigGrid'] = self.integ.signalLevel + data['specData'] = self.integ.levels + if self.sig: + data['sigGridOrig'] = self.sig.gridOrig + data['sigGridDim'] = self.sig.gridDim + data['sigGridSize'] = self.sig.gridSize + if self.sig and self.integ: + data['sigGrid'] = self.integ.signalLevel + data['sigData'] = self.integ.cellSigLevels + data['sigGrid'] = self.integ.signalLevel pickle.dump(data, outfile, protocol=-1) #output csv file with cell pos,dir,len - sig? From 6c34ad45f149a0d6ae2365774ea43c3d583722b5 Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Wed, 17 Jun 2020 19:30:30 -0400 Subject: [PATCH 25/26] Correct rendering of signal grid, scaled to max --- Scripts/Draw2DPDF.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Scripts/Draw2DPDF.py b/Scripts/Draw2DPDF.py index fb464df4..af920463 100644 --- a/Scripts/Draw2DPDF.py +++ b/Scripts/Draw2DPDF.py @@ -19,13 +19,13 @@ class CellModellerPDFGenerator(Canvas): def __init__(self, name, data, bg_color): self.name = name self.states = data.get('cellStates') - self.signals = False - if 'specData' in data: - self.signals = True - self.signal_levels = data.get('sigGrid') - self.signal_grid_orig = data.get('sigGridOrig') - self.signal_grid_dim = data.get('sigGridDim') - self.signal_grid_size = data.get('sigGridSize') + + self.signal_levels = data.get('sigGrid', None) + self.signal_grid_orig = data.get('sigGridOrig', None) + self.signal_grid_dim = data.get('sigGridDim', None) + self.signal_grid_size = data.get('sigGridSize', None) + self.signals = self.signal_levels is not None + self.parents = data.get('lineage') self.data = data self.bg_color = bg_color @@ -93,7 +93,7 @@ def draw_chamber(self): self.line(-100, -16, 100, -16) self.line(-100, 16, 100, 16) - def draw_signals(self, index=0, scale=0.0192, z=2): + def draw_signals(self, index=0, scale=0.0192, z=0): ''' Function for drawing signal grids, currently limited to 1 signal a plane at a fixed z-axis level through the grid @@ -109,12 +109,13 @@ def draw_signals(self, index=0, scale=0.0192, z=2): self.signal_grid_dim, \ self.signal_levels levels = levels.reshape(dim) + mx = levels[index,:,:,z].max() l = list(map(float,l)) for i in range(dim[1]): x = l[0]*i + orig[0] for j in range(dim[2]): y = l[1]*j + orig[1] - lvls = levels[index,i,j,z]/scale + lvls = levels[index,i,j,z]/mx mxsig0 = max(lvls, mxsig0) self.setFillColorRGB(lvls, 0, 0) self.rect(x-l[0]/2.0, y-l[1]/2.0, l[0], l[1], stroke=0, fill=1) @@ -211,7 +212,7 @@ def main(): '''(w,h) = pdf.computeBox() sqrt2 = math.sqrt(2) world = (w/sqrt2,h/sqrt2)''' - world = (450,450) + world = (150,150) # Page setup page = (20,20) From b896f3109387307b773960627c3656ba72bdcf6a Mon Sep 17 00:00:00 2001 From: Tim Rudge Date: Wed, 8 Jul 2020 09:16:58 -0400 Subject: [PATCH 26/26] Add load geometry button to only load cell position, orientation, length. Not fully tested --- CellModeller/GUI/PyGLCMViewer.py | 18 +++ CellModeller/GUI/PyGLGUI.ui | 28 ++++ .../Integration/CLEulerSigIntegrator.py | 12 +- CellModeller/Signalling/GridDiffusion.py | 4 +- CellModeller/Simulator.py | 21 +++ Examples/ex5_colonySector.py | 130 +++++------------- Scripts/video.sh | 3 +- 7 files changed, 117 insertions(+), 99 deletions(-) diff --git a/CellModeller/GUI/PyGLCMViewer.py b/CellModeller/GUI/PyGLCMViewer.py index a53a1b38..20e5134d 100644 --- a/CellModeller/GUI/PyGLCMViewer.py +++ b/CellModeller/GUI/PyGLCMViewer.py @@ -151,6 +151,24 @@ def reset(self): self.frameNo = 0 self.updateGL() + @pyqtSlot() + def loadGeometry(self): + options = QFileDialog.Options() + options |= QFileDialog.DontUseNativeDialog + qs,_ = QFileDialog.getOpenFileName(self, 'Load geometry from pickle file', '', '*.pickle', options=options) + if qs: + filename = str(qs) + print(filename) + data = pickle.load(open(filename,'rb')) + if isinstance(data, dict): + self.sim.loadGeometryFromPickle(data) + self.frameNo = self.sim.stepNum + if self.run: + self.frameNo += 1 + self.updateGL() + else: + print("Pickle is in an unsupported format, sorry") + @pyqtSlot() def loadPickle(self): options = QFileDialog.Options() diff --git a/CellModeller/GUI/PyGLGUI.ui b/CellModeller/GUI/PyGLGUI.ui index 6a6dd7eb..3fb41184 100644 --- a/CellModeller/GUI/PyGLGUI.ui +++ b/CellModeller/GUI/PyGLGUI.ui @@ -75,6 +75,7 @@ + @@ -116,6 +117,17 @@ Ctrl+O + + + Load Geometry + + + Load geometry from pickle file + + + Ctrl+l + + Load Pickle @@ -224,6 +236,22 @@ + + actionLoadGeometry + triggered() + PyGLCMViewer + loadGeometry() + + + -1 + -1 + + + 589 + 357 + + + actionLoadPickle triggered() diff --git a/CellModeller/Integration/CLEulerSigIntegrator.py b/CellModeller/Integration/CLEulerSigIntegrator.py index 7e75b062..39a972b9 100644 --- a/CellModeller/Integration/CLEulerSigIntegrator.py +++ b/CellModeller/Integration/CLEulerSigIntegrator.py @@ -63,8 +63,6 @@ def __init__(self, sim, nSignals, nSpecies, maxCells, sig, regul=None, boundcond self.regul = regul self.boundcond = boundcond - self.cellStates = sim.cellStates - self.nCells = len(self.cellStates) self.nSpecies = nSpecies self.nSignals = nSignals @@ -99,10 +97,18 @@ def __init__(self, sim, nSignals, nSpecies, maxCells, sig, regul=None, boundcond self.initArrays() #self.initKernels() + self.setCellStates(sim.cellStates) + + + def setCellStates(self, cs): # set the species for existing states to views of the levels array - cs = self.cellStates + self.cellStates = cs + self.nCells = len(self.cellStates) + self.cellSigLevels[:,:] = 0 for id,c in list(cs.items()): c.species = self.specLevel[c.idx,:] + c.signals = self.cellSigLevels[c.idx,:] + self.celltype[c.idx] = numpy.int32(c.cellType) def makeViews(self): diff --git a/CellModeller/Signalling/GridDiffusion.py b/CellModeller/Signalling/GridDiffusion.py index 8689ee40..f863e897 100644 --- a/CellModeller/Signalling/GridDiffusion.py +++ b/CellModeller/Signalling/GridDiffusion.py @@ -40,8 +40,10 @@ def __init__(self, sim, nSignals, gridDim, gridSize, gridOrig, D, adv=None, init self.dV = reduce(lambda x, y: x * y, self.gridSize) self.regul = regul - self.cellStates = sim.cellStates + self.setCellStates(sim.cellStates) + def setCellStates(self, cs): + self.cellStates = cs def setBiophysics(self, biophysics): self.biophys = biophysics diff --git a/CellModeller/Simulator.py b/CellModeller/Simulator.py index 0ee2eb3d..49d30f12 100644 --- a/CellModeller/Simulator.py +++ b/CellModeller/Simulator.py @@ -407,6 +407,27 @@ def writePickle(self, csv=False): pickle.dump(data, outfile, protocol=-1) #output csv file with cell pos,dir,len - sig? + # Populate simulation from saved data pickle + def loadGeometryFromPickle(self, data): + self.setCellStates(data['cellStates']) + self.lineage = data['lineage'] + idx_map = {} + id_map = {} + idmax = 0 + for id,state in data['cellStates'].items(): + idx_map[state.id] = state.idx + id_map[state.idx] = state.id + if id>idmax: + idmax=id + self.idToIdx = idx_map + self.idxToId = id_map + self._next_id = idmax+1 + self._next_idx = len(data['cellStates']) + if self.integ: + self.integ.setCellStates(self.cellStates) + if self.sig: + self.integ.setCellStates(self.cellStates) + # Populate simulation from saved data pickle def loadFromPickle(self, data): self.setCellStates(data['cellStates']) diff --git a/Examples/ex5_colonySector.py b/Examples/ex5_colonySector.py index ecfee7c4..97965b7f 100644 --- a/Examples/ex5_colonySector.py +++ b/Examples/ex5_colonySector.py @@ -1,122 +1,64 @@ import random from CellModeller.Regulation.ModuleRegulator import ModuleRegulator from CellModeller.Biophysics.BacterialModels.CLBacterium import CLBacterium -import numpy as np +from CellModeller.GUI import Renderers +import numpy import math -l = 60. -K = 10. -n = 1.5 -Kn = K**n -_b_ = 10. -_N0_ = 10. +N0 = 10 def setup(sim): # Set biophysics, signalling, and regulation models - biophys = CLBacterium(sim, jitter_z=False) + biophys = CLBacterium(sim, jitter_z=False, gamma = 100, max_cells=100000, max_planes=1) regul = ModuleRegulator(sim, sim.moduleName) # use this file for reg too # Only biophys and regulation sim.init(biophys, regul, None, None) - sim.addCell(cellType=0, pos=(0,0,0)) + #biophys.addPlane((0,0,0),(0,0,1),1.0) #Base plane + #biophys.addPlane((10,0,0),(-1,0,0),1.0) + #biophys.addPlane((-10,0,0),(1,0,0),1.0) + #biophys.addPlane((0,10,0),(0,-1,0),1.0) + #biophys.addPlane((0,-10,0),(0,1,0),1.0) - if sim.is_gui: - # Add some objects to draw the models - from CellModeller.GUI import Renderers - therenderer = Renderers.GLBacteriumRenderer(sim) - sim.addRenderer(therenderer) + sim.addCell(cellType=0, pos=(0,0,0)) - sim.pickleSteps = 10 + # Add some objects to draw the models + therenderer = Renderers.GLBacteriumRenderer(sim) + sim.addRenderer(therenderer) + sim.pickleSteps = 1 def init(cell): cell.targetVol = 3.5 + random.uniform(0.0,0.5) cell.growthRate = 1.0 - cell.N0 = 0 - cell.p1, cell.p2, cell.p3 = 0,0,0 - -def repressilator_step(cell, dt): - t = 0 - #for i in range(10000): - while t cell.targetVol: cell.divideFlag = True - repressilator_step(cell, 0.01*60) def divide(parent, d1, d2): d1.targetVol = 3.5 + random.uniform(0.0,0.5) d2.targetVol = 3.5 + random.uniform(0.0,0.5) - - # Binomial separation of plasmids and proteins - d1.N0 = np.random.binomial(parent.N0, 0.5) - d2.N0 = parent.N0 - d1.N0 - d1.p1 = np.random.binomial(parent.p1, 0.5) - d2.p1 = parent.p1 - d1.p1 - d1.p2 = np.random.binomial(parent.p2, 0.5) - d2.p2 = parent.p2 - d1.p2 - d1.p3 = np.random.binomial(parent.p3, 0.5) - d2.p3 = parent.p3 - d1.p3 + plasmids = [0]*parent.n_a*2 + [1]*parent.n_b*2 + random.shuffle(plasmids) + d1.n_a = 0 + d1.n_b = 0 + d2.n_a = 0 + d2.n_b = 0 + for p in plasmids[:N0]: + if p == 0: d1.n_a +=1 + else: d1.n_b +=1 + for p in plasmids[N0:2*N0]: + if p == 0: d2.n_a +=1 + else: d2.n_b +=1 + assert parent.n_a + parent.n_b == N0 + assert d1.n_a + d1.n_b == N0 + assert d2.n_a + d2.n_b == N0 + assert parent.n_a*2 == d1.n_a+d2.n_a + assert parent.n_b*2 == d1.n_b+d2.n_b + assert parent.n_a > 0 or (d1.n_a == 0 and d2.n_a == 0) + assert parent.n_b > 0 or (d1.n_b == 0 and d2.n_b == 0) diff --git a/Scripts/video.sh b/Scripts/video.sh index b48c0b4c..9e269fae 100755 --- a/Scripts/video.sh +++ b/Scripts/video.sh @@ -14,7 +14,8 @@ done for f in $( ls *.pdf ); do NAME=`basename $f .pdf` convert \ - -verbose \ + -colorspace RGB \ + -verbose \ -density 150 \ $NAME.pdf \ $NAME.png