[Avida-cvs] [Avida2-svn] r146 - trunk/source/python/AvidaGui2

kaben at myxo.css.msu.edu kaben at myxo.css.msu.edu
Fri Apr 15 00:37:10 PDT 2005


Author: kaben
Date: 2005-04-15 03:37:10 -0400 (Fri, 15 Apr 2005)
New Revision: 146

Modified:
   trunk/source/python/AvidaGui2/pyMapProfile.py
   trunk/source/python/AvidaGui2/pyOnePop_GraphCtrl.py
   trunk/source/python/AvidaGui2/pyOnePop_PetriDishCtrl.py
   trunk/source/python/AvidaGui2/pyPetriDishCtrl.py
Log:

* Changes to Avida-ED petri dish viewer.
- Optimizations -- Avida-ED can now display large populations, and
  updates quickly.
- Map updates immediately on switching modes.
- Rescales occur over course of 40 updates instead of ten.
- Map and graph both start in fitness mode.
- Initial zoom is chosen to keep whole petri dish in view.
  - Zooming needs more work; only some some factors work without causing
    grid lines to look funky.



Modified: trunk/source/python/AvidaGui2/pyMapProfile.py
===================================================================
--- trunk/source/python/AvidaGui2/pyMapProfile.py	2005-04-15 07:32:42 UTC (rev 145)
+++ trunk/source/python/AvidaGui2/pyMapProfile.py	2005-04-15 07:37:10 UTC (rev 146)
@@ -4,6 +4,7 @@
 
 class pyMapProfile:
   def __init__(self):
+    self.m_color_cache_size = 201
 
     def continuousIndexer(idx_functor):
       def continuousIndexingFunction(population_cell_item, min, range):
@@ -41,7 +42,7 @@
         self.m_sup_tol_coef = 0.1
         self.m_inf_rescale_rate = 0.0
         self.m_sup_rescale_rate = 0.0
-        self.m_updates_to_rescale = 10
+        self.m_updates_to_rescale = 40
         self.m_should_reset = True
 
       def reset(self, should_reset):
@@ -82,14 +83,8 @@
     NullRng = lambda p: (0, 0)
     MeritRng = lambda p: (0, p.GetStats().GetMaxMerit())
     FitnessRng = lambda p: (0, p.GetStats().GetMaxFitness())
-    def GestationTimeRng(p):
-      return 0, max(
-        p.GetCell(n).IsOccupied() and p.GetCell(n).GetOrganism().GetPhenotype().GetGestationTime() or 0
-        for n in range(p.GetSize()))
-    def SizeRng(p):
-      return 0, max(
-        p.GetCell(n).IsOccupied() and p.GetCell(n).GetOrganism().GetPhenotype().GetGenomeLength() or 0
-        for n in range(p.GetSize()))
+    GestationTimeRng = lambda p: (0, p.GetStats().GetMaxGestationTime())
+    SizeRng = lambda p: (0, p.GetStats().GetMaxGenomeLength())
 
 
     def sigmoid(x, midpoint, steepness):
@@ -105,6 +100,14 @@
       s = sigmoid(1 - x, 0.1, 30) * 255
       return QColor(h, s, v, QColor.Hsv)
 
+    self.m_color_cache = [sigmoidDoubleToColor(float(n)/(self.m_color_cache_size - 1)) for n in range(self.m_color_cache_size)]
+    def sigmoidColorLookup(x):
+      sup = self.m_color_cache_size - 1
+      x *= sup
+      x = sup < x and sup or x
+      x = x < 0 and 0 or x
+      return self.m_color_cache[int(x)]
+
     self.m_entries = (
     #  Mode Name,        Indexer
       ('None',
@@ -115,22 +118,22 @@
       ('Merit',
         continuousIndexer(MeritIdx),
         gradualLinScaleUpdater(MeritRng),
-        sigmoidDoubleToColor
+        sigmoidColorLookup
         ),
       ('Fitness',
         continuousIndexer(FitnessIdx),
         gradualLinScaleUpdater(FitnessRng),
-        sigmoidDoubleToColor
+        sigmoidColorLookup
         ),
       ('Gestation Time',
         continuousIndexer(GestationTimeIdx),
         gradualLinScaleUpdater(GestationTimeRng),
-        sigmoidDoubleToColor
+        sigmoidColorLookup
         ),
       ('Size',
         continuousIndexer(SizeIdx),
         gradualLinScaleUpdater(SizeRng),
-        sigmoidDoubleToColor
+        sigmoidColorLookup
         ),
       #('Genotype',       GenotypeIdx,),
       #('Lineage',        LineageIdx,),

Modified: trunk/source/python/AvidaGui2/pyOnePop_GraphCtrl.py
===================================================================
--- trunk/source/python/AvidaGui2/pyOnePop_GraphCtrl.py	2005-04-15 07:32:42 UTC (rev 145)
+++ trunk/source/python/AvidaGui2/pyOnePop_GraphCtrl.py	2005-04-15 07:37:10 UTC (rev 146)
@@ -55,6 +55,9 @@
 
     self.m_graph_ctrl.setAxisTitle(QwtPlot.xBottom, "Time (updates)")
     self.m_graph_ctrl.setAxisAutoScale(QwtPlot.xBottom)
+
+    # Start with second graph mode -- "Average Fitness".
+    self.m_combo_box.setCurrentItem(2)
     self.modeActivatedSlot(self.m_combo_box.currentItem())
 
     self.connect(

Modified: trunk/source/python/AvidaGui2/pyOnePop_PetriDishCtrl.py
===================================================================
--- trunk/source/python/AvidaGui2/pyOnePop_PetriDishCtrl.py	2005-04-15 07:32:42 UTC (rev 145)
+++ trunk/source/python/AvidaGui2/pyOnePop_PetriDishCtrl.py	2005-04-15 07:37:10 UTC (rev 146)
@@ -34,12 +34,13 @@
     self.m_map_profile = pyMapProfile()
     for i in range(self.m_map_profile.getSize()):
       self.m_mode_combobox.insertItem(self.m_map_profile.getModeName(i))
-    self.m_mode_combobox.setCurrentItem(1)
+
+    # Start with second map mode -- "Fitness".
+    self.m_mode_combobox.setCurrentItem(2)
     self.m_mode_index = self.m_mode_combobox.currentItem()
     self.modeActivatedSlot(self.m_mode_index)
+    #self.m_petri_dish_ctrl.emit(PYSIGNAL("zoomSig"), (self.m_petri_dish_ctrl.m_initial_target_zoom,))
 
-    self.m_petri_dish_ctrl.emit(PYSIGNAL("zoomSig"), (9,))
-
   def setAvidaSlot(self, avida):
     old_avida = self.m_avida
     self.m_avida = avida
@@ -82,13 +83,15 @@
     self.m_mode_index = index
     self.m_petri_dish_ctrl.setIndexer(self.m_map_profile.getIndexer(self.m_mode_index))
     self.m_petri_dish_ctrl.setColorLookupFunctor(self.m_map_profile.getColorLookup(self.m_mode_index))
+    self.m_petri_dish_ctrl.m_should_update_all = True
     self.m_gradient_scale_ctrl.setColorLookup(self.m_map_profile.getColorLookup(self.m_mode_index))
     self.m_updater = self.m_map_profile.getUpdater(self.m_mode_index)
     self.m_updater and self.m_updater.reset(True)
 
     self.m_avida and self.m_avida.m_avida_threaded_driver.m_lock.release()
+    self.avidaUpdatedSlot(True)
 
-  def avidaUpdatedSlot (self):
+  def avidaUpdatedSlot(self, should_update_all = False):
     if self.m_updater:
       (old_min, old_max) = self.m_updater.getRange()
       (min, max) = self.m_avida and self.m_updater.updateRange(self.m_avida.m_population) or (0, 0)
@@ -97,11 +100,12 @@
         self.m_gradient_scale_ctrl.activate(True)
         self.m_petri_dish_ctrl.setRange(min, max)
         self.m_updater.reset(False)
+        should_update_all = True
     else:
       self.m_gradient_scale_ctrl.setRange(0, 0)
       self.m_gradient_scale_ctrl.activate(True)
       self.m_petri_dish_ctrl.setRange(0, 0)
-    self.m_petri_dish_ctrl.updateCellItems()
+    self.m_petri_dish_ctrl.updateCellItems(should_update_all)
 
     stats = update = None
     if self.m_avida: stats = self.m_avida.m_population.GetStats()

Modified: trunk/source/python/AvidaGui2/pyPetriDishCtrl.py
===================================================================
--- trunk/source/python/AvidaGui2/pyPetriDishCtrl.py	2005-04-15 07:32:42 UTC (rev 145)
+++ trunk/source/python/AvidaGui2/pyPetriDishCtrl.py	2005-04-15 07:37:10 UTC (rev 146)
@@ -40,99 +40,101 @@
     self.m_indexer = None
     self.m_color_lookup_functor = None
     self.m_background_rect = None
+    self.m_change_list = None
+    self.m_occupied_cells_ids = []
 
+    self.m_target_dish_width = 270
+    self.m_target_dish_scaling = 5.
+    self.m_map_cell_width = 5
+
     self.connect( self.m_session_mdl.m_session_mdtr, PYSIGNAL("setAvidaSig"), self.setAvidaSlot)
     self.connect( self.m_canvas_view, PYSIGNAL("orgClickedOnSig"), self.m_session_mdl.m_session_mdtr, PYSIGNAL("orgClickedOnSig"))
 
   def setColorLookupFunctor(self, color_lookup_functor):
     self.m_color_lookup_functor = color_lookup_functor
 
+  def createNewCellItem(self, n):
+    self.m_occupied_cells_ids.append(n)
+    return pyPopulationCellItem(
+      self.m_avida.m_population.GetCell(n),
+      (n%self.m_world_w) * self.m_map_cell_width,
+      (n/self.m_world_w) * self.m_map_cell_width,
+      self.m_map_cell_width,
+      self.m_map_cell_width,
+      self.m_canvas)
+
   def setAvidaSlot(self, avida):
     old_avida = self.m_avida
     self.m_avida = avida
     if(old_avida):
-      old_avida.removeGuiWorkFunctor(self)
       del old_avida
     if(self.m_avida):
       pass
 
-    self.m_map_cell_w = 5
-    self.m_map_cell_h = 5
-    world_w = cConfig.GetWorldX()
-    world_h = cConfig.GetWorldY()
+    self.m_change_list = self.m_avida.m_avida_threaded_driver.GetChangeList()
 
+    self.m_world_w = cConfig.GetWorldX()
+    self.m_world_h = cConfig.GetWorldY()
+    self.m_initial_target_zoom = int(self.m_target_dish_width / self.m_world_w)
+    print "self.m_map_cell_width", self.m_map_cell_width
+    
+    self.emit(PYSIGNAL("zoomSig"), (self.m_initial_target_zoom,))
+
     if self.m_canvas: del self.m_canvas
-    self.m_canvas = QCanvas(self.m_map_cell_w * world_w, self.m_map_cell_h * world_h)
+    self.m_canvas = QCanvas(self.m_map_cell_width * self.m_world_w, self.m_map_cell_width * self.m_world_h)
     self.m_canvas.setBackgroundColor(Qt.darkGray)
     self.m_canvas_view.setCanvas(self.m_canvas)
     if self.m_background_rect: del self.m_background_rect
-    self.m_background_rect = QCanvasRectangle(0, 0, self.m_map_cell_w * world_w, self.m_map_cell_h * world_h, self.m_canvas)
+    self.m_background_rect = QCanvasRectangle(
+      0, 0,
+      self.m_map_cell_width * self.m_world_w,
+      self.m_map_cell_width * self.m_world_h,
+      self.m_canvas)
     self.m_background_rect.setBrush(QBrush(Qt.black))
     self.m_background_rect.setPen(QPen(Qt.black))
     self.m_background_rect.show()
     self.m_background_rect.setZ(0.0)
 
     if self.m_cell_info: del self.m_cell_info
-    self.m_cell_info = [pyPopulationCellItem(
-      self.m_avida.m_population.GetCell(n),
-      (n%world_w) * self.m_map_cell_w,
-      (n/world_w) * self.m_map_cell_h,
-      self.m_map_cell_w,
-      self.m_map_cell_h,
-      self.m_canvas) for  n in range(world_w * world_h)]
+    self.m_cell_info = [None] * self.m_world_w * self.m_world_h
+    self.m_occupied_cells_ids = []
 
     self.m_thread_work_cell_item_index = 0
     self.m_cs_min_value = 0
     self.m_cs_value_range = 0
     self.m_changed_cell_items = self.m_cell_info[:]
-    while self.doSomeWork(self.m_avida): pass
-    self.updateCellItems()
-    self.m_avida.addGuiWorkFunctor(self)
+    self.updateCellItems(True)
 
   def setRange(self, min, max):
     self.m_cs_min_value = min
     self.m_cs_value_range = max - min
 
   def setIndexer(self, indexer):
-    print "pyPetriDishCtrl.setIndexer"
     self.m_indexer = indexer
 
-    if self.m_cell_info:
-      for cell_info_item in self.m_cell_info:
-        cell_info_item.updateColorUsingFunctor(None)
-      self.m_canvas.update()
-      self.m_changed_cell_items = self.m_cell_info[:]
+  def updateCellItems(self, should_update_all = False):
+    def updateCellItem(cell_id):
+      if self.m_cell_info[cell_id] is None:
+        self.m_cell_info[cell_id] = self.createNewCellItem(cell_id)
+      cell_info_item = self.m_cell_info[cell_id]
+      self.m_indexer(cell_info_item, self.m_cs_min_value, self.m_cs_value_range)
+      cell_info_item.updateColorUsingFunctor(self.m_color_lookup_functor)
 
+    if should_update_all and self.m_cell_info:
+      for cell_id in self.m_occupied_cells_ids:
+        updateCellItem(cell_id)
+    elif self.m_change_list and self.m_cell_info:
+      for index in range(self.m_change_list.GetChangeCount()):
+        updateCellItem(self.m_change_list[index])
 
-  def doSomeWork(self, avida):
-    if self.m_indexer:
-      for x in range(len(self.m_cell_info)):
-        if len(self.m_cell_info) <= self.m_thread_work_cell_item_index:
-          self.m_thread_work_cell_item_index = 0
-          return False
-        else:
-          cell_info_item = self.m_cell_info[self.m_thread_work_cell_item_index]
-          if self.m_indexer(cell_info_item, self.m_cs_min_value, self.m_cs_value_range):
-            self.m_changed_cell_items.append(cell_info_item)
-          self.m_thread_work_cell_item_index += 1
-      return True
-    else:
-      return False
-
-  def updateCellItems(self):
-    for cell_info_item in self.m_changed_cell_items:
-      cell_info_item.updateColorUsingFunctor(self.m_color_lookup_functor)
-    self.m_changed_cell_items = []
     if self.m_canvas: self.m_canvas.update()
 
   def extractPopulationSlot(self):
     population_dict = {}
-    world_w = cConfig.GetWorldX()
-    world_h = cConfig.GetWorldY()
-    for x in range(world_w):
-      for y in range(world_h):
+    for x in range(self.m_world_w):
+      for y in range(self.m_world_h):
         if self.m_avida != None:
-          cell = self.m_avida.m_population.GetCell(x + world_w*y)
+          cell = self.m_avida.m_population.GetCell(x + self.m_world_w*y)
           if cell.IsOccupied() == True:
             organism = cell.GetOrganism()
             genome = organism.GetGenome()
@@ -142,6 +144,6 @@
   def zoomSlot(self, zoom_factor):
     if self.m_canvas_view:
       m = QWMatrix()
-      m.scale(zoom_factor/5.0, zoom_factor/5.0)
+      m.scale(zoom_factor/self.m_target_dish_scaling, zoom_factor/self.m_target_dish_scaling)
       self.m_canvas_view.setWorldMatrix(m)
 




More information about the Avida-cvs mailing list