Source code for steps.API_1.visual.DynamicComponent

####################################################################################
#
#    STEPS - STochastic Engine for Pathway Simulation
#    Copyright (C) 2007-2023 Okinawa Institute of Science and Technology, Japan.
#    Copyright (C) 2003-2006 University of Antwerp, Belgium.
#    
#    See the file AUTHORS for details.
#    This file is part of STEPS.
#    
#    STEPS is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License version 3,
#    as published by the Free Software Foundation.
#    
#    STEPS is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#    GNU General Public License for more details.
#    
#    You should have received a copy of the GNU General Public License
#    along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################   
###

from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph.opengl as gl
import numpy as np
import random

import steps.API_1.geom as sgeom
from steps.API_1.geom import INDEX_DTYPE

[docs]class VisualTetsSpec(gl.GLScatterPlotItem): """ Visualization component for species in tetrahedrons. Parameters: * id ID of the component * display Parent SimDisplay object * mesh STEPS Tetmesh object * sim STEPS solver object * tets List of tetrahedron indices * spec_id ID of the species * spec_color Color of the species * spec_size Size of the species * max_nspec Maximum number of species can be visualized in the component * max_density Maximum density of species can be visualized in the component * auto_adjust Boolean flag for auto adjustment of visualized species counts """ def __init__(self, id, display, mesh, sim, tets, spec_id, spec_color = None, spec_size = 0.2, max_nspec = 10000, max_density = 1000e18, auto_adjust = True): """ Constructor. """ self.id = id self.display = display self.bound_min = [float('Inf'), float('Inf'), float('Inf')] self.bound_max = [-float('Inf'), -float('Inf'), -float('Inf')] self.mesh = mesh self.sim = sim self.spec_id = spec_id if spec_color is None: self.spec_color = [random.random(), random.random(), random.random(), random.random()] else: self.spec_color = spec_color self.spec_size = spec_size self.max_nspec = max_nspec self.max_density = max_density self.auto_adjust = auto_adjust self.tets = np.array(tets, dtype = INDEX_DTYPE) self.counts = np.zeros(self.tets.size) sim.getBatchTetSpecCountsNP(self.tets, spec_id, self.counts) point_counts = self.counts.astype(np.uint32) total = np.sum(point_counts) if total > max_nspec: total = self.__reduce(point_counts) data = np.zeros(int(total) * 3) self.mesh.genTetVisualPointsNP(self.tets, point_counts, data) data *= display.scale data.shape = -1, 3 gl.GLScatterPlotItem.__init__(self, pos = data, color=self.spec_color, size=self.spec_size, pxMode=False) display.addItem(self) def __reduce(self, point_counts): """ Reduce the number of points being generated. """ self.mesh.reduceBatchTetPointCountsNP(self.tets, point_counts, self.max_density) total = np.sum(point_counts) temp_density = self.max_density while total > self.max_nspec and self.auto_adjust: temp_density *= (self.max_nspec / total) self.mesh.reduceBatchTetPointCountsNP(self.tets, point_counts, temp_density) total = np.sum(point_counts) return total
[docs] def updateItem(self): """ Update the component. """ self.sim.getBatchTetSpecCountsNP(self.tets, self.spec_id, self.counts) point_counts = self.counts.astype(np.uint32) total = np.sum(point_counts) if total > self.max_nspec: total = self.__reduce(point_counts) data = np.zeros(int(total) * 3) self.mesh.genTetVisualPointsNP(self.tets, point_counts, data) data *= self.display.scale data.shape = -1, 3 self.setData(pos = data, color=self.spec_color)
[docs] def setMaxNSpec(self, new_value): """ Set the maximum number of species can be visualized in the component """ self.max_nspec = new_value
[docs] def getMaxNSpec(self): """ Get the maximum number of species can be visualized in the component """ return self.max_nspec
[docs] def setSpecColor(self, color): """ Set the color of the species """ self.spec_color = color self.setData(color=self.spec_color)
[docs] def getSpecColor(self): """ Get the color of the species """ return self.spec_color
[docs] def setAutoAdjust(self, condition): """ Set if the component automatically adjust the number of visualizing points according the maximum count and maximum density """ self.auto_adjust = condition
[docs] def getAutoAdjust(self): """ Get if the component automatically adjust the number of visualizing points according the maximum count and maximum density """ return self.auto_adjust
[docs] def setMaxDensity(self, density): """ Set the maximum density of species can be visualized in the component """ self.max_density = density
[docs] def getMaxDensity(self): """ Get the maximum density of species can be visualized in the component """ return self.max_density
[docs] def setSpecSize(self, size): """ Set the size of the points """ self.spec_size = size self.setData(size = self.spec_size)
[docs] def getSpecSize(self): """ Get the size of the points """ return self.spec_size
[docs]class VisualCompSpec(VisualTetsSpec): """ Visualization component for species in compartment. Parameters: * id ID of the component * display Parent SimDisplay object * mesh STEPS Tetmesh object * sim STEPS solver object * comp_id ID of the compartment * spec_id ID of the species * spec_color Color of the species * spec_size Size of the species * max_nspec Maximum number of species can be visualized in the component * max_density Maximum density of species can be visualized in the component * auto_adjust Boolean flag for auto adjustment of visualized species counts """ def __init__(self, id, display, mesh, sim, comp_id, spec_id, spec_color = None, spec_size = 0.2, max_nspec = 100000, max_density = 1000e18, auto_adjust = True): """ Constructor. """ self.comp_id = comp_id tets = sgeom.castToTmComp(mesh.getComp(comp_id)).getAllTetIndices() VisualTetsSpec.__init__(self, id, display, mesh, sim, tets, spec_id, spec_color, spec_size, max_nspec, max_density, auto_adjust)
[docs]class VisualROITetsSpec(VisualTetsSpec): """ Visualization component for species in Region of Interest tetrahedrons. Parameters: * id ID of the component * display Parent SimDisplay object * mesh STEPS Tetmesh object * sim STEPS solver object * roi_id ID of the Region of Interest * spec_id ID of the species * spec_color Color of the species * spec_size Size of the species * max_nspec Maximum number of species can be visualized in the component * max_density Maximum density of species can be visualized in the component * auto_adjust Boolean flag for auto adjustment of visualized species counts """ def __init__(self, id, display, mesh, sim, roi_id, spec_id, spec_color = None, spec_size = 0.2, max_nspec = 100000, max_density = 1000e18, auto_adjust = True): """ Constructor. """ self.roi_id = roi_id tets = mesh.getROIData(roi_id) VisualTetsSpec.__init__(self, id, display, mesh, sim, tets, spec_id, spec_color, spec_size, max_nspec, max_density, auto_adjust)
[docs]class VisualTrisSpec(gl.GLScatterPlotItem): """ Visualization component for species in triangles. Parameters: * id ID of the component * display Parent SimDisplay object * mesh STEPS Tetmesh object * sim STEPS solver object * tris List of triangle indices * spec_id ID of the species * spec_color Color of the species * spec_size Size of the species * max_nspec Maximum number of species can be visualized in the component * max_density Maximum density of species can be visualized in the component * auto_adjust Boolean flag for auto adjustment of visualized species counts """ def __init__(self, id, display, mesh, sim, tris, spec_id, spec_color = None, spec_size = 0.2, max_nspec = 100000, max_density = 1000e12, auto_adjust = True): """ Constructor. """ self.id = id self.display = display self.bound_min = [float('Inf'), float('Inf'), float('Inf')] self.bound_max = [-float('Inf'), -float('Inf'), -float('Inf')] self.mesh = mesh self.sim = sim self.spec_id = spec_id if spec_color == None: self.spec_color = [random.random(), random.random(), random.random(), random.random()] else: self.spec_color = spec_color self.spec_size = spec_size self.max_nspec = max_nspec self.max_density = max_density self.auto_adjust = auto_adjust self.tris = np.array(tris, dtype = INDEX_DTYPE) self.counts = np.zeros(self.tris.size) sim.getBatchTriSpecCountsNP(self.tris, spec_id, self.counts) point_counts = self.counts.astype(np.uint32) total = np.sum(point_counts) if total > max_nspec: total = self.__reduce(point_counts) data = np.zeros(int(total) * 3) self.mesh.genTriVisualPointsNP(self.tris, point_counts, data) data *= display.scale data.shape = -1, 3 gl.GLScatterPlotItem.__init__(self, pos = data, color=self.spec_color, size=self.spec_size, pxMode=False) display.addItem(self) def __reduce(self, point_counts): """ Reduce the number of points being generated. """ self.mesh.reduceBatchTriPointCountsNP(self.tris, point_counts, self.max_density) total = np.sum(point_counts) temp_density = self.max_density while total > self.max_nspec and self.auto_adjust: temp_density *= (self.max_nspec / total) self.mesh.reduceBatchTriPointCountsNP(self.tris, point_counts, temp_density) total = np.sum(point_counts) return total
[docs] def updateItem(self): """ Update the component. """ self.sim.getBatchTriSpecCountsNP(self.tris, self.spec_id, self.counts) self.point_counts = self.counts.astype(np.uint32) self.total = np.sum(self.point_counts) if self.total > self.max_nspec: self.__reduce() data = np.zeros(int(self.total) * 3) self.mesh.genTriVisualPointsNP(self.tris, self.point_counts, data) data *= self.display.scale data.shape = -1, 3 self.setData(pos = data, color=self.spec_color)
[docs] def setMaxNSpec(self, new_value): """ Set the maximum number of species can be visualized in the component """ self.max_nspec = new_value
[docs] def getMaxNSpec(self): """ Get the maximum number of species can be visualized in the component """ return self.max_nspec
[docs] def setSpecColor(self, color): """ Set the color of the species """ self.spec_color = color self.setData(color=self.spec_color)
[docs] def getSpecColor(self): """ Get the color of the species """ return self.spec_color
[docs] def setAutoAdjust(self, condition): """ Set if the component automatically adjust the number of visualizing points according the maximum count and maximum density """ self.auto_adjust = condition
[docs] def getAutoAdjust(self): """ Get if the component automatically adjust the number of visualizing points according the maximum count and maximum density """ return self.auto_adjust
[docs] def setMaxDensity(self, density): """ Set the maximum density of species can be visualized in the component """ self.max_density = density
[docs] def getMaxDensity(self): """ Get the maximum density of species can be visualized in the component """ return self.max_density
[docs] def setSpecSize(self, size): """ Set the size of the points """ self.spec_size = size self.setData(size = self.spec_size)
[docs] def getSpecSize(self): """ Get the size of the points """ return self.spec_size
[docs]class VisualPatchSpec(VisualTrisSpec): """ Visualization component for species in patch. Parameters: * id ID of the component * display Parent SimDisplay object * mesh STEPS Tetmesh object * sim STEPS solver object * patch_id ID of the patch * spec_id ID of the species * spec_color Color of the species * spec_size Size of the species * max_nspec Maximum number of species can be visualized in the component * max_density Maximum density of species can be visualized in the component * auto_adjust Boolean flag for auto adjustment of visualized species counts """ def __init__(self, id, display, mesh, sim, patch_id, spec_id, spec_color = None, spec_size = 0.2, max_nspec = 100000, max_density = 1000e12, auto_adjust = True): """ Constructor. """ self.patch_id = patch_id tris = sgeom.castToTmPatch(mesh.getPatch(patch_id)).getAllTriIndices() VisualTrisSpec.__init__(self, id, display, mesh, sim, tris, spec_id, spec_color, spec_size, max_nspec, max_density, auto_adjust)
[docs]class VisualROITrisSpec(VisualTrisSpec): """ Visualization component for species in Region of Interest triangles. Parameters: * id ID of the component * display Parent SimDisplay object * mesh STEPS Tetmesh object * sim STEPS solver object * roi_id ID of the Region of Interest * spec_id ID of the species * spec_color Color of the species * spec_size Size of the species * max_nspec Maximum number of species can be visualized in the component * max_density Maximum density of species can be visualized in the component * auto_adjust Boolean flag for auto adjustment of visualized species counts """ def __init__(self, id, display, mesh, sim, roi_id, spec_id, spec_color = None, spec_size = 0.2, max_nspec = 100000, max_density = 1000e12, auto_adjust = True): """ Constructor. """ self.roi_id = roi_id tris = mesh.getROIData(roi_id) VisualTrisSpec.__init__(self, id, display, mesh, sim, tris, spec_id, spec_color, spec_size, max_nspec, max_density, auto_adjust)
[docs]class VisualTrisChannel(gl.GLScatterPlotItem): """ Visualization component for channel species in triangles. Parameters: * id ID of the component * display Parent SimDisplay object * mesh STEPS Tetmesh object * sim STEPS solver object * tris List of triangle indices * specs_colors Species-Color mapping dictionary * spec_size Size of the species """ def __init__(self, id, display, mesh, sim, tris, specs_colors, spec_size = 0.1): """ Constructor. """ self.id = id self.display = display self.bound_min = [float('Inf'), float('Inf'), float('Inf')] self.bound_max = [-float('Inf'), -float('Inf'), -float('Inf')] self.mesh = mesh self.sim = sim self.specs_colors = specs_colors self.spec_size = spec_size self.tris = np.array(tris, dtype = INDEX_DTYPE) # total counts of species channels in eaxh tris total_counts = np.zeros(self.tris.size) individual_counts = np.zeros(self.tris.size) for s in specs_colors.keys(): self.sim.getBatchTriSpecCountsNP(self.tris, s, individual_counts) total_counts += individual_counts self.starts = np.insert(np.cumsum(total_counts), 0, 0) total = sum(total_counts) data = np.zeros(int(total) * 3) point_counts = total_counts.astype(np.uint32) self.mesh.genTriVisualPointsNP(self.tris, point_counts, data) data *= display.scale data.shape = -1, 3 self.color = np.zeros(int(total) * 4).reshape(-1, 4) current_counter = np.zeros(self.tris.size, dtype = INDEX_DTYPE) for s in self.specs_colors.keys(): sim.getBatchTriSpecCountsNP(self.tris, s, individual_counts) for t in range(self.tris.size): self.color[int(self.starts[t] + current_counter[t]) : int(self.starts[t] + current_counter[t] + individual_counts[t])] = self.specs_colors[s] current_counter[t] += individual_counts[t] gl.GLScatterPlotItem.__init__(self, pos = data, color=self.color, size=self.spec_size, pxMode=False) display.addItem(self)
[docs] def updateItem(self): """ Update the component. """ current_counter = np.zeros(self.tris.size, dtype = INDEX_DTYPE) individual_counts = np.zeros(self.tris.size) for s in self.specs_colors.keys(): self.sim.getBatchTriSpecCountsNP(self.tris, s, individual_counts) for t in range(self.tris.size): self.color[int(self.starts[t] + current_counter[t]) : int(self.starts[t] + current_counter[t] + individual_counts[t])] = self.specs_colors[s] current_counter[t] += individual_counts[t] self.setData(color = self.color)
[docs] def setSpecColor(self, spec, color): """ Set the color of the species """ self.specs_colors[spec] = color updateItem
[docs] def getSpecColor(self, spec): """ Get the color of the species """ return self.specs_colors[spec]
[docs] def setSpecSize(self, size): """ Set the size of the points """ self.spec_size = size self.setData(size = self.spec_size)
[docs] def getSpecSize(self): """ Get the size of the points """ return self.spec_size
[docs]class VisualPatchChannel(VisualTrisChannel): """ Visualization component for channel species in a patch. Parameters: * id ID of the component * display Parent SimDisplay object * mesh STEPS Tetmesh object * sim STEPS solver object * patch_id ID of the patch * specs_colors Species-Color mapping dictionary * spec_size Size of the species """ def __init__(self, id, display, mesh, sim, patch_id, specs_colors, spec_size = 0.1): """ Constructor. """ self.patch_id = patch_id tris = sgeom.castToTmPatch(mesh.getPatch(patch_id)).getAllTriIndices() VisualTrisChannel.__init__(self, id, display, mesh, sim, tris, specs_colors, spec_size)
[docs]class VisualROITrisChannel(VisualTrisChannel): """ Visualization component for channel species in Region of Interest trangles. Parameters: * id ID of the component * display Parent SimDisplay object * mesh STEPS Tetmesh object * sim STEPS solver object * roi_id ID of the Region of Interest * specs_colors Species-Color mapping dictionary * spec_size Size of the species """ def __init__(self, id, display, mesh, sim, roi_id, specs_colors, spec_size = 0.1): """ Constructor. """ self.roi_id = roi_id tris = mesh.getROIData(roi_id) VisualTrisChannel.__init__(self, id, display, mesh, sim, tris, specs_colors, spec_size)