def __init__(self, databaseFilePath): ShowBase.__init__(self) self.speed = 40 # Mouse and camera movement init self.mouseX_last = 0 self.mouseY_last = 0 self.rotateCamera = False self.move_z = 0 self.env = cEnvironment(self) self.env.CreateBasement() # to not be lost if there is nothing around self.env.SetupLights() self.env.SetupCamera() width = self.win.getProperties().getXSize() height = self.win.getProperties().getYSize() self.gui = cGUI(width, height, self.loader, visApp=self) self.env.SetCameraLoc(self.gui.cameraStartLoc) self.databaseFilePath = databaseFilePath self.bakeReader = BakeReader(self.databaseFilePath) self.interaction = cInteraction(self) self.interaction.SetupKeys() self.interaction.SetupOnClick() self.taskMgr.add(self.update, "main loop") self.accept(self.win.getWindowEvent(), self.interaction.onWindowEvent) self.HTMObjects = {} self.allHTMobjectsCreated = False self.oneOfObjectsCreationFinished = False self.taskMgr.add(self.gfxCreationWorker, "gfxCreation") #self.gfxCreationThread = threading.Thread(target=self.gfxCreationWorker, args=()) #---- self.iterationDataUpdate = False self.BuildStructure() # hand over this value to the gui to be able to validate user inputs # -1 because predictive cells are + 1 self.gui.cntIterations = self.bakeReader.cntIterations - 1 self.iteration = 0 self.initIterationLoaded = False self.tmrRun = 0 self.autoRunIteration = 0
def run(self, databaseFilePath, layout): self.bakeReader = BakeReader(databaseFilePath) self.bakeReader.OpenDatabase() self.bakeReader.LoadDataStreams() with open(os.path.join(os.getcwd(),'..','dashVis','layouts',layout+'.txt')) as f: cfgLayout = json.load(f) plotsPerRow = cfgLayout['plotsPerRow'] figures = [] cnt = 0 for stream in cfgLayout['streams']: try: data = self.bakeReader.dataStreams[stream['name']].allData except KeyError: print('Requested data stream "'+str(stream['name'])+'" was not found in the database!') return if stream['type'] == 'line': fig = go.Figure(data=go.Scatter(x=data[0, :], y=data[1, :],line=dict(color=self.randomColors[cnt]))) figures.append([stream['name'],fig]) # Set theme, margin, and annotation in layout fig.update_layout( title=stream['name'], xaxis_title="iteration", yaxis_title=stream['yaxis'], template="plotly_dark", #margin=dict(r=10, t=25, b=40, l=60), # annotations=[ # dict( # text="abc Source: NOAA", # showarrow=False, # xref="paper", # yref="paper", # x=0, # y=0) # ] ) cnt+=1 if cnt>=len(self.randomColors): cnt=0 columnClassName = "col-sm-12" if plotsPerRow == 4: columnClassName = "col-sm-3" elif plotsPerRow == 3: columnClassName = "col-sm-4" elif plotsPerRow == 2: columnClassName = "col-sm-6" graphs = [html.Div( ([html.Div([dcc.Graph( id='plot_'+x[0], figure=x[1] )], className=columnClassName) for x in figures] ),className="row") ] childs = [ html.H4( children='Dash vis', style={ 'textAlign': 'center', 'color': self.colors['text'] } ),] childs += graphs self.app.layout = html.Div(style={'backgroundColor': self.colors['background']}, children=childs) self.app.run_server(debug=True, use_reloader=False)
class cDashVis(object): def __init__(self): self.bakeReader = None #external_stylesheets = ['https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css'] self.app = dash.Dash(__name__,) #external_stylesheets=external_stylesheets) self.colors = { 'background': '#111111', 'text': '#7FDBFF' } number_of_colors = 30 random.seed(1) print(random.randint(1,50)) self.randomColors = ["#" + ''.join([random.choice('0123456789ABCDEF') for j in range(6)]) for i in range(number_of_colors)] def run(self, databaseFilePath, layout): self.bakeReader = BakeReader(databaseFilePath) self.bakeReader.OpenDatabase() self.bakeReader.LoadDataStreams() with open(os.path.join(os.getcwd(),'..','dashVis','layouts',layout+'.txt')) as f: cfgLayout = json.load(f) plotsPerRow = cfgLayout['plotsPerRow'] figures = [] cnt = 0 for stream in cfgLayout['streams']: try: data = self.bakeReader.dataStreams[stream['name']].allData except KeyError: print('Requested data stream "'+str(stream['name'])+'" was not found in the database!') return if stream['type'] == 'line': fig = go.Figure(data=go.Scatter(x=data[0, :], y=data[1, :],line=dict(color=self.randomColors[cnt]))) figures.append([stream['name'],fig]) # Set theme, margin, and annotation in layout fig.update_layout( title=stream['name'], xaxis_title="iteration", yaxis_title=stream['yaxis'], template="plotly_dark", #margin=dict(r=10, t=25, b=40, l=60), # annotations=[ # dict( # text="abc Source: NOAA", # showarrow=False, # xref="paper", # yref="paper", # x=0, # y=0) # ] ) cnt+=1 if cnt>=len(self.randomColors): cnt=0 columnClassName = "col-sm-12" if plotsPerRow == 4: columnClassName = "col-sm-3" elif plotsPerRow == 3: columnClassName = "col-sm-4" elif plotsPerRow == 2: columnClassName = "col-sm-6" graphs = [html.Div( ([html.Div([dcc.Graph( id='plot_'+x[0], figure=x[1] )], className=columnClassName) for x in figures] ),className="row") ] childs = [ html.H4( children='Dash vis', style={ 'textAlign': 'center', 'color': self.colors['text'] } ),] childs += graphs self.app.layout = html.Div(style={'backgroundColor': self.colors['background']}, children=childs) self.app.run_server(debug=True, use_reloader=False)
class cExplorer3D(ShowBase): def __init__(self, databaseFilePath): ShowBase.__init__(self) self.speed = 40 # Mouse and camera movement init self.mouseX_last = 0 self.mouseY_last = 0 self.rotateCamera = False self.move_z = 50 self.env = cEnvironment(self) self.env.CreateBasement() # to not be lost if there is nothing around self.env.SetupLights() self.env.SetupCamera() width = self.win.getProperties().getXSize() height = self.win.getProperties().getYSize() self.gui = cGUI(width, height, self.loader, visApp=self) self.databaseFilePath = databaseFilePath self.bakeReader = BakeReader(self.databaseFilePath) self.interaction = cInteraction(self) self.interaction.SetupKeys() self.interaction.SetupOnClick() self.taskMgr.add(self.update, "main loop") self.accept(self.win.getWindowEvent(), self.interaction.onWindowEvent) self.HTMObjects = {} self.allHTMobjectsCreated = False self.oneOfObjectsCreationFinished = False self.gfxCreationThread = threading.Thread( target=self.gfxCreationWorker, args=()) #---- self.iterationDataUpdate = False self.BuildStructure() # hand over this value to the gui to be able to validate user inputs # -1 because predictive cells are + 1 self.gui.cntIterations = self.bakeReader.cntIterations - 1 self.iteration = 0 self.initIterationLoaded = False self.autoRunIteration = 0 def BuildStructure(self): self.bakeReader.OpenDatabase() self.bakeReader.BuildStructure() obj = "HTM1" if obj not in self.HTMObjects: printLog("HTM object creation! Name:" + str(obj)) # create HTM object newObj = cHTM(self, self.loader, obj) newObj.getNode().reparentTo(self.render) # create inputs for inp in self.bakeReader.inputs: printLog("Creating input: " + str(inp), verbosityHigh) newObj.CreateInput( name=inp, count=self.bakeReader.inputs[inp].size, rows=int(math.sqrt(self.bakeReader.inputs[inp].size)), ) # create layers for lay in self.bakeReader.layers: printLog("Creating layer: " + str(lay), verbosityHigh) newObj.CreateLayer( name=lay, nOfColumnsPerLayer=int( self.bakeReader.layers[lay].params['sp_columnCount']), nOfCellsPerColumn=int(self.bakeReader.layers[lay]. params['tm_cellsPerColumn']), ) self.HTMObjects[obj] = newObj self.gfxCreationThread.start() def LoadIteration(self, iteration): self.iteration = iteration for obj in self.HTMObjects: for inp in self.HTMObjects[obj].inputs: self.bakeReader.LoadInput(inp, iteration) for ly in self.HTMObjects[obj].layers: self.bakeReader.LoadActiveColumns(ly, iteration) self.bakeReader.LoadWinnerCells(ly, iteration) self.bakeReader.LoadPredictiveCells( ly, iteration + 1) #take predictions for t+1 if self.gui.showPredictionCorrectness: self.bakeReader.LoadPredictiveCells( ly, iteration, loadPrevious=True ) #take also predictions for t to be able to calculate correctness self.bakeReader.LoadActiveCells(ly, iteration) self.bakeReader.LoadProximalSynapses(ly, [ self.gui.columnID, ], iteration) #can't load distal synapses here, because they are a big size # loading just for one cell per - user click self.updateHTMstate( ) # update state of the HTM objects and connections def updateHTMstate(self): printLog("Data change! Updating HTM state", verbosityMedium) self.gui.setIteration(self.iteration) obj = "HTM1" # go through all incoming inputs for i in self.bakeReader.inputs: # dict printLog("Updating state of input: " + str(i), verbosityHigh) # find matching input in local structure self.HTMObjects[obj].inputs[i].UpdateState( self.bakeReader.inputs[i].bits, self.bakeReader.inputs[i].stringValue, ) # go through all incoming layers for l in self.bakeReader.layers: # dict if self.HTMObjects[obj].layers[l].gfxCreationFinished: printLog("Updating state of layer: " + str(l), verbosityHigh) # find matching layer in local structure self.HTMObjects[obj].layers[l].UpdateState( self.bakeReader.layers[l].activeColumns, self.bakeReader.layers[l].activeCells, self.bakeReader.layers[l].winnerCells, self.bakeReader.layers[l].predictiveCells, self.bakeReader.layers[l].prev_predictiveCells, showPredictionCorrectness=self.gui. showPredictionCorrectness, showBursting=self.gui.showBursting) self.oneOfObjectsCreationFinished = False self.UpdateProximalAndDistalData() self.gui.UpdateCellDescription() def UpdateProximalAndDistalData(self): if self.gui.focusedCell is None: return # -------- proximal and distal synapses ----------------------- if self.gui.showProximalSynapses: self.ShowProximalSynapses(self.gui.focusedPath[0], self.gui.focusedPath[1], self.gui.columnID, self.gui.showOnlyActiveProximalSynapses) if self.gui.showDistalSynapses: self.ShowDistalSynapses(self.gui.focusedPath[0], self.gui.focusedPath[1], self.gui.columnID, self.gui.cellID) # if self.gui.showProximalSynapses and self.gui.focusedCell is not None: # self.client.reqProximalData() # else: # for obj in self.base.HTMObjects.values(): # obj.DestroyProximalSynapses() # # #do not request distal data if we don't want to show them or if this layer doesn't have TM # if self.gui.showDistalSynapses and self.gui.focusedCell is not None: # self.client.reqDistalData() # else: # for obj in self.base.HTMObjects.values(): # destroy synapses if they not to be shown # obj.DestroyDistalSynapses() # ----------------------------------------------------------- def ShowProximalSynapses( self, obj, layerName, column, showOnlyActive ): # reads the synapses from the database and show them layer = self.bakeReader.layers[layerName] self.bakeReader.LoadProximalSynapses(layerName, [column], self.iteration) # load it if column not in layer.proximalSynapses: printLog("Don't have proximal data for requested column:" + str(column) + " of layer:" + str(layerName)) self.HTMObjects[obj].layers[layerName].DestroyProximalSynapses() return self.HTMObjects[obj].layers[layerName].ShowProximalSynapses( column, layer.proximalSynapses[column], layer.proximalInputs, #names of inputs self.HTMObjects[obj].inputs, layer.params['sp_synPermConnected'], showOnlyActive) def ShowDistalSynapses(self, obj, layerName, column, cell): layer = self.bakeReader.layers[layerName] gotSomeData = self.bakeReader.LoadDistalSynapses( layerName, column, cell, self.iteration) # load it if not gotSomeData: printLog("Don't have any distal synapses to show for this cell.") self.HTMObjects[obj].layers[layerName].minicolumns[column].cells[ cell].DestroyDistalSynapses() return self.HTMObjects[obj].layers[layerName].minicolumns[column].cells[ cell].CreateDistalSynapses(self.HTMObjects[obj], self.HTMObjects[obj].layers[layerName], layer.distalSynapses[cell], layer.distalInputs) def update(self, task): self.gui.update() self.interaction.Update() if self.allHTMobjectsCreated and not self.initIterationLoaded: # wait till the objects are created, then load iteration 0 self.LoadIteration(0) self.initIterationLoaded = True if self.gui.gotoReq >= 0: self.LoadIteration(self.gui.gotoReq) self.gui.gotoReq = -1 if self.gui.capture: self.LoadIteration(self.autoRunIteration) self.autoRunIteration += 1 if self.autoRunIteration > 997: self.gui.capture = False os.system( "ffmpeg -y -framerate 10 -i screenshots/%01d.jpg -codec copy screenshots/recording.mkv" ) self.win.saveScreenshot('screenshots/' + str(self.autoRunIteration) + '.jpg') return task.cont def gfxCreationWorker(self): time.sleep( 5 ) # need to delay this, there was SIGSEG faults, probably during creation of objects thread collision happens printLog("Starting GFX worker thread") while True: # finishing HTM objects creation on the run if not self.allHTMobjectsCreated: allFinished = True for obj in self.HTMObjects: if not self.HTMObjects[obj].gfxCreationFinished: allFinished = False self.HTMObjects[obj].CreateGfxProgressively() if self.HTMObjects[ obj].gfxCreationFinished: # it just finished GFX creation self.oneOfObjectsCreationFinished = True if allFinished: self.allHTMobjectsCreated = True printLog("GFX worker: all objects finished") break if self.gui.terminating: break printLog("GFX worker: quit")
class cExplorer3D(ShowBase): def __init__(self, databaseFilePath): ShowBase.__init__(self) self.speed = 40 # Mouse and camera movement init self.mouseX_last = 0 self.mouseY_last = 0 self.rotateCamera = False self.move_z = 0 self.env = cEnvironment(self) self.env.CreateBasement() # to not be lost if there is nothing around self.env.SetupLights() self.env.SetupCamera() width = self.win.getProperties().getXSize() height = self.win.getProperties().getYSize() self.gui = cGUI(width, height, self.loader, visApp=self) self.env.SetCameraLoc(self.gui.cameraStartLoc) self.databaseFilePath = databaseFilePath self.bakeReader = BakeReader(self.databaseFilePath) self.interaction = cInteraction(self) self.interaction.SetupKeys() self.interaction.SetupOnClick() self.taskMgr.add(self.update, "main loop") self.accept(self.win.getWindowEvent(), self.interaction.onWindowEvent) self.HTMObjects = {} self.allHTMobjectsCreated = False self.oneOfObjectsCreationFinished = False self.taskMgr.add(self.gfxCreationWorker, "gfxCreation") #self.gfxCreationThread = threading.Thread(target=self.gfxCreationWorker, args=()) #---- self.iterationDataUpdate = False self.BuildStructure() # hand over this value to the gui to be able to validate user inputs # -1 because predictive cells are + 1 self.gui.cntIterations = self.bakeReader.cntIterations - 1 self.iteration = 0 self.initIterationLoaded = False self.tmrRun = 0 self.autoRunIteration = 0 def BuildStructure(self): self.bakeReader.OpenDatabase() self.bakeReader.BuildStructure() obj = "HTM1" if obj not in self.HTMObjects: printLog("HTM object creation! Name:" + str(obj)) # create HTM object newObj = cHTM(self, self.loader, obj, self.gui) newObj.getNode().reparentTo(self.render) # create regions for reg in self.bakeReader.regions: if self.CheckForUnification( reg ) is not None: # check if there is region for unification printLog("Creating unificated region: " + str(reg), verbosityHigh) newObj.CreateUnificatedRegion( name=reg, regionData=self.bakeReader.regions[reg]) else: printLog("Creating region: " + str(reg), verbosityHigh) newObj.CreateRegion( name=reg, regionData=self.bakeReader.regions[reg]) self.HTMObjects[obj] = newObj # need to do it here due to unknown order creation for reg in self.HTMObjects[obj].regions: uniReg = self.CheckForUnification(reg) if uniReg is not None: self.HTMObjects[obj].regions[reg].SetUnifiedTMRegion( uniReg) # link SP->TM self.HTMObjects[obj].regions[uniReg].SetUnifiedSPRegion( reg) # link TM -> SP # assign position of regions in 3D space # load positionOverride override = None try: with open( os.path.join( os.path.dirname(self.bakeReader.databaseFilePath), 'regionPositionOverride.ini'), 'r') as file: override = json.loads(file.read()) except Exception as e: print("Error while loading position override file!") print(str(e)) xShift = 0 yShift = 0 xcolShift = 0 layerHeight = 0 column = 0 # each 100's is one category - means these layers are next to each other, instead of stacking on top if override is not None: for layer in override: for reg in override[layer]: if reg in self.HTMObjects[obj].regions.keys(): region = self.HTMObjects[obj].regions[reg] if column < ( int(layer) // 100 ): # for each 100 in layerID, shift it by large step on X axis column = (int(layer) // 100) xcolShift += 200 yShift = 0 region.setPosition([xShift + xcolShift, yShift]) x, y = region.getBoundingBoxSize() xShift += x layerHeight = max(layerHeight, y) yShift += layerHeight + 20 # layer completed layerHeight = 0 xShift = 0 #self.gfxCreationThread.start() # checks if the "reg" SPregion is unified with TMregion, returning name of TMRegion def CheckForUnification(self, reg): if self.bakeReader.regions[reg].type in [ 'SPRegion' ]: # applies only for SPRegion now # check if SP is connected to TM or TM like region, with minicolumns for link in self.bakeReader.links.values( ): # SP region is source and his out is bottomUpOut if link.sourceRegion == reg and link.sourceOutput == 'bottomUpOut' and\ self.bakeReader.regions[link.destinationRegion].type in ['TMRegion', 'ApicalTMPairRegion']: return link.destinationRegion return None def LoadIteration(self, iteration): self.iteration = iteration for obj in self.HTMObjects: for reg in self.HTMObjects[obj].regions: self.bakeReader.LoadAllRegionData(reg, iteration) # we need to store also predictive cells for t+1 self.bakeReader.LoadRegionData(reg, iteration + 1, "predictedCells", "next_predictedCells") #self.bakeReader.LoadProximalSynapses(reg,[self.gui.columnID,], iteration) # can't load distal synapses here, because they are a big size # loading just for one cell per - user click self.updateHTMstate( ) # update state of the HTM objects and connections def updateHTMstate(self): printLog("Data change! Updating HTM state", verbosityMedium) self.gui.setIteration(self.iteration) obj = "HTM1" # hardcoded for now # go through all regions for reg in self.bakeReader.regions: # dict if reg in self.HTMObjects[obj].regions and self.HTMObjects[ obj].regions[reg].gfxCreationFinished: printLog("Updating state of region: " + str(reg), verbosityHigh) self.HTMObjects[obj].regions[reg].UpdateState( self.bakeReader.regions[reg]) self.oneOfObjectsCreationFinished = False self.UpdateConnections() self.gui.UpdateCellDescription() # this updates focused cell / column connections def UpdateConnections(self): if self.gui.focusedCell is None: return obj = self.gui.focusedPath[0] regionName = self.gui.focusedPath[1] column = self.gui.columnID cell = self.gui.cellID region = self.HTMObjects[obj].regions[regionName] regionData = self.bakeReader.regions[regionName] # cleans all data, do not call if you want to stack data for more cells/columns for example self.bakeReader.CleanCellConnections(regionName) self.bakeReader.CleanColumnConnections(regionName) # ---------------------------- Column connections SYNAPSES --------------------------------------------------------------- for connType, typeFiles in region.connections.items( ): # iterate over conn types for typeFile in typeFiles: # iterate over connection file types (can be multiple per connectionType) self.UpdateColumnConnections(regionName, region, column, obj, connectionType=connType, connectionTypeFile=typeFile) # ---------------------------- Cell connections SYNAPSES ----------------------------------------------------------- for connType, typeFiles in region.connections.items( ): # iterate over conn types for typeFile in typeFiles: # iterate over connection file types (can be multiple per connectionType) self.UpdateCellConnections(obj=obj, connectionType=connType, connectionTypeFile=typeFile, regionName=regionName, column=column, cell=cell) def UpdateColumnConnections(self, regionName, region, column, obj, connectionType, connectionTypeFile): createConn = False destroyConn = False if connectionType == 'proximal': if self.gui.showProximalSynapses: createConn = True else: destroyConn = True if createConn: # determine region to get data from if hasattr(region, 'unifiedSPRegion'): # if it has unified SP region data_regionName = region.unifiedSPRegion else: data_regionName = regionName # load the data self.bakeReader.LoadColumnConnections( connectionType=connectionType, connectionTypeFile=connectionTypeFile, regionName=data_regionName, iteration=self.iteration, colID=column, connectedOnly=self.gui.showOnlyConnectedSynapses ) # proximal, but without prefix, because they are the only one if connectionType not in self.bakeReader.regions[data_regionName].columnConnections or \ column not in [x[0] for x in self.bakeReader.regions[data_regionName].columnConnections[connectionType]]: printLog("Don't have column data for requested column:" + str(column) + " of region:" + str(regionName)) # self.HTMObjects[obj].regions[regionName].DestroyProximalSynapses() return self.HTMObjects[obj].regions[regionName].DestroySynapses( synapseType=connectionType) self.HTMObjects[obj].regions[regionName].ShowSynapses( self.HTMObjects["HTM1"].regions, self.bakeReader, synapsesType=connectionType, column=column, cell=-1, onlyActive=self.gui.showOnlyActiveSynapses) if destroyConn: self.HTMObjects[obj].regions[regionName].DestroySynapses( synapseType=connectionType) # loads data, destroys previous synapses, creates new ones def UpdateCellConnections(self, obj, connectionType, connectionTypeFile, regionName, column, cell): createConn = False destroyConn = False if connectionType == 'distal': if self.gui.showDistalSynapses: createConn = True else: destroyConn = True if connectionType == 'apical': if self.gui.showApicalSynapses: createConn = True else: destroyConn = True if connectionType == 'proximal' and self.HTMObjects[obj].regions[ regionName].type == 'py.ColumnPoolerRegion': # special case if self.gui.showProximalSynapses: createConn = True else: destroyConn = True if createConn: if hasattr(self.HTMObjects[obj].regions[regionName], 'nOfCellsPerColumn'): cellID = column * self.HTMObjects[obj].regions[ regionName].nOfCellsPerColumn + cell else: cellID = cell # load it self.bakeReader.LoadCellConnections( connectionType=connectionType, connectionTypeFile=connectionTypeFile, regionName=regionName, iteration=self.iteration, cellID=cellID, connectedOnly=self.gui.showOnlyConnectedSynapses) self.HTMObjects[obj].regions[regionName].DestroySynapses( synapseType=connectionType) self.HTMObjects[obj].regions[regionName].ShowSynapses( self.HTMObjects["HTM1"].regions, self.bakeReader, synapsesType=connectionType, column=column, cell=cell, onlyActive=self.gui.showOnlyActiveSynapses) if destroyConn: self.HTMObjects[obj].regions[regionName].DestroySynapses( synapseType=connectionType) def update(self, task): self.gui.update() self.interaction.Update() if self.allHTMobjectsCreated and not self.initIterationLoaded: # wait till the objects are created, then load iteration 0 self.LoadIteration(0) self.initIterationLoaded = True # --------------------------- GUI COMMANDS --------------------------------------------------------------------- if self.gui.gotoReq >= 0: self.LoadIteration(self.gui.gotoReq) self.gui.gotoReq = -1 if self.gui.cmdRun and ( self.tmrRun - time.time()) > 1: # each second perform step +1 self.LoadIteration(self.iteration + 1) self.tmrRun = time.time() if self.gui.cmdStop: self.gui.cmdRun = False self.gui.cmdStop = False if self.gui.capture: path = os.path.join(os.path.dirname(self.databaseFilePath), "capture") if not os.path.exists(path): os.makedirs(path) self.LoadIteration(self.autoRunIteration) self.autoRunIteration += 1 if self.autoRunIteration > self.gui.cntIterations: self.gui.capture = False os.system("ffmpeg -y -framerate 10 -i " + path + "/%01d.jpg -codec copy " + path + "/recording.mkv") self.win.saveScreenshot(path + '/' + str(self.autoRunIteration) + '.jpg') # -------------------------------------------------------------------------------------------------------------- if self.gui.updateConnections: print("Updating connections due to change in GUI settings") self.UpdateConnections() self.gui.updateConnections = False if self.gui.terminating: sys.exit() return task.cont def gfxCreationWorker(self, task): #time.sleep(20) # need to delay this, there was SIGSEG faults, probably during creation of objects thread collision happens #printLog("Starting GFX worker thread") # finishing HTM objects creation on the run if not self.allHTMobjectsCreated: allFinished = True for obj in self.HTMObjects: if not self.HTMObjects[obj].gfxCreationFinished: allFinished = False self.HTMObjects[obj].CreateGfxProgressively() if self.HTMObjects[ obj].gfxCreationFinished: # it just finished GFX creation self.oneOfObjectsCreationFinished = True if allFinished: self.allHTMobjectsCreated = True printLog("GFX worker: all objects finished") if self.allHTMobjectsCreated or self.gui.terminating: return 0 # this return causes not to call this method anymore else: return task.cont