[Avida-SVN] r3357 - branches/developers/avida-edward/source/python/AvidaGui2
welsberr at myxo.css.msu.edu
welsberr at myxo.css.msu.edu
Wed Aug 5 09:45:51 PDT 2009
Author: welsberr
Date: 2009-08-05 12:45:50 -0400 (Wed, 05 Aug 2009)
New Revision: 3357
Added:
branches/developers/avida-edward/source/python/AvidaGui2/change_notes.txt
branches/developers/avida-edward/source/python/AvidaGui2/mypython
branches/developers/avida-edward/source/python/AvidaGui2/pyAvidaEdCtrl.py
branches/developers/avida-edward/source/python/AvidaGui2/pyDiversitySandbox.py
branches/developers/avida-edward/source/python/AvidaGui2/pyGridMaster.py
branches/developers/avida-edward/source/python/AvidaGui2/pyMDMkEnv.py
branches/developers/avida-edward/source/python/AvidaGui2/pyMDSetupFormView.ui
branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_MDView.ui
branches/developers/avida-edward/source/python/AvidaGui2/pyPRNGState.py
Modified:
branches/developers/avida-edward/source/python/AvidaGui2/pyEduWorkspaceCtrl.py
branches/developers/avida-edward/source/python/AvidaGui2/pyFreezerCtrl.py
branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_GraphCtrl.py
branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_PetriDishCtrl.py
branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_StatsCtrl.py
branches/developers/avida-edward/source/python/AvidaGui2/pyPetriConfigureCtrl.py
branches/developers/avida-edward/source/python/AvidaGui2/pyPetriConfigureView.ui
branches/developers/avida-edward/source/python/AvidaGui2/pyPetriDishCtrl.py
branches/developers/avida-edward/source/python/AvidaGui2/pyReadFreezer.py
branches/developers/avida-edward/source/python/AvidaGui2/pyWriteAvidaCfgEvent.py
branches/developers/avida-edward/source/python/AvidaGui2/pyWriteToFreezer.py
Log:
Additional files for the Multi-Dish version
Added: branches/developers/avida-edward/source/python/AvidaGui2/change_notes.txt
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/change_notes.txt (rev 0)
+++ branches/developers/avida-edward/source/python/AvidaGui2/change_notes.txt 2009-08-05 16:45:50 UTC (rev 3357)
@@ -0,0 +1,11 @@
+
+
+Code for grabbing the population genomes is in
+
+pyPetriDishCtrl.py :
+ def extractPopulationSlot(self, send_reset_signal = False, send_quit_signal = False):
+
+Will need to do that to compute diversity metrics
+
+
+
Added: branches/developers/avida-edward/source/python/AvidaGui2/mypython
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/mypython (rev 0)
+++ branches/developers/avida-edward/source/python/AvidaGui2/mypython 2009-08-05 16:45:50 UTC (rev 3357)
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Build environment python
+# /Users/welsberr/aed_env/Build/AvidaOneStepLocal/bin/python $1
+
+# Run-time python
+/Users/welsberr/avida/avida-ed/Avida-Ed-onestep-qt3/Build/avida_bld/Avida-ED/bin/Avida-ED.app/Contents/MacOS/python $1
Property changes on: branches/developers/avida-edward/source/python/AvidaGui2/mypython
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/developers/avida-edward/source/python/AvidaGui2/pyAvidaEdCtrl.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyAvidaEdCtrl.py (rev 0)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyAvidaEdCtrl.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -0,0 +1,66 @@
+"""
+
+pyAvidaCtrl.py
+
+Routines to handle running avidacore plus updating a database backend.
+
+Theory of operation:
+
+Initialize, run, pause, or reset a single instance of Avida
+
+Within a run:
+- collect data on a per-update basis.
+
+"""
+
+class AvidaCtrl():
+ def __init__(self):
+ """
+ Basic initialization for Avida instance
+ """
+ pass
+
+ def beginRun(self):
+ """
+ Start a run based on current settings
+ """
+ pass
+
+ def pauseRun(self):
+ """
+ Pause an ongoing run
+ """
+ pass
+
+ def killRun(self):
+ """
+ Take down a run.
+ """
+
+ pass
+
+ def atUpdate(self):
+ """
+ Method called at the end of an update.
+ This is a place to connect things that should run at
+ each update.
+
+ """
+ pass
+
+ def perUpdateDataDump(self):
+ """
+ Method to dump the data from a run at each update
+ """
+ # Check for being in a run, exit if not
+ # Go through entire multidish to extract informtion
+ # Cell traversal
+ # Organism:
+ # - Is it new? Add a new record?
+ # - Fitness, Met. Rate, Gest. Time,
+ # - Phenotype
+ # Population properties
+ # Diversity measures
+ pass
+
+
Added: branches/developers/avida-edward/source/python/AvidaGui2/pyDiversitySandbox.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyDiversitySandbox.py (rev 0)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyDiversitySandbox.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -0,0 +1,529 @@
+#!/Users/welsberr/avida/avida-ed/Avida-Ed-onestep-qt3/Build/AvidaOneStepLocal/bin/python
+
+# Python program to test various diversity measures
+
+import os
+import sys
+import math
+
+import random
+# From tutorial:
+# >>> random.choice(['apple', 'pear', 'banana'])
+# 'apple'
+# >>> random.sample(xrange(100), 10) # sampling without replacement
+# [30, 83, 16, 4, 8, 81, 41, 50, 18, 33]
+# >>> random.random()
+# random float
+# 0.17970987693706186
+# >>> random.randrange(6)
+# random integer chosen from range(6)
+
+from UserDict import UserDict
+
+class UnrealWorld():
+ """
+ UnrealWorld provides a class for generating an x by y grid of random
+ or mutated genotypes and phenotypes.
+ """
+ # Class properties
+ genealts = "abcdefghijklmnopqrstuvwxyz"
+ phenalts = "01"
+ slength = 50
+ mutrate = 0.02
+ uw = []
+
+ # Class methods
+
+ def __init__(self,x=300,y=300,mutrate=0.02):
+ """
+ __init__ for UnrealWorld, sets up genome and phenotypes for a randomly generated
+ population.
+ """
+ parent = ""
+ for ii in range(x): # (ii = 0; ii < x; ii++):
+ for jj in range(y): # (jj = 0; jj < y; jj++):
+ self.uw[ii][jj] = self.mutgenome(self.slength,parent,self.genealts,self.mutrate)
+ print self.uw[ii][jj]
+ print "\n"
+
+ def mutgenome(self, slength=50, parent="", alts="01", mutrate=0.02):
+ """
+ mutgenome generates a new genome of a specified length. If the parent
+ genome is blank, all bases are randomly determined. Else the parent
+ genome is copied except if a random variable fals below the mutation
+ rate, in which case it is randomly picked.
+ """
+ # Start with a blank string
+ mystr = ""
+ # Now copy or generate bases as needed
+ for kk in range(0, slength-1): # (kk = 0; kk < slength; kk++):
+ myrand = random.random()
+ if ((kk >= len(parent)) or (myrand <= mutrate)):
+ # Select newbase from alternatives
+ mystr += alts[random.randrange(len(alts))]
+ else:
+ mystr += parent[kk]
+ return mystr
+
+class diversity():
+ """
+ diversity: a class to provide a variety of methods for measures of diversity
+
+ There are a number of arguments given at Lou Jost's site that look convincing
+ that there is a distinction between a diversity index and a diversity measure.
+ Jost gives the formulae for converting common diversity indices into diversity
+ measures, which have the form of estimates of effective number of species. Therefore,
+ I am adding those to the diversity results from various methods here.
+
+ Site: http://www.loujost.com/Statistics%20and%20Physics/Diversity%20and%20Similarity/DiversitySimilarityHome.htm
+ """
+ def __init__(self):
+ """
+ __init__ there is no initialization required
+ """
+ pass
+
+ def factorial(self,x):
+ """
+ factorial
+ Provides a factorial function to handle large values of x. Essentially chooses
+ to approximate the factorial when x exceeds a threshold.
+ """
+ # Regular factorial processing
+ # if (300 > x):
+ if (0):
+ xf = 1;
+ for ii in range(2,x+1):
+ xf *= ii
+ else: # Too big, so aproximate
+ # Stirling's approximation
+ # n! ~ n^n e^(-n) sqrt(2 * pi * n) (1 + 1/(12n))
+ xf = (x ** x) * (math.e ** (-x)) * math.sqrt(2 * math.pi * x) * (1.0 + 1.0 / (12 * x))
+ return xf
+
+
+ def nmatches(self,s1,s2):
+ """
+ nmatches
+
+ Returns the number of characters that match between
+ two strings.
+ """
+ mc = 0
+ mn = min(len(s1),len(s2))
+ for ii in range(mn):
+ if (s1[ii] == s2[ii]):
+ mc += 1
+ return((mc,mn))
+
+ def ndiffs(self,s1,s2):
+ """
+ ndiffs
+
+ Returns the number of differences between two strings.
+ """
+ (mc,mn) = self.nmatches(s1,s2)
+
+ return ((mn - mc, mn))
+
+ def addToDictWithIncrement(self,dict,key):
+ """
+ addToDict
+
+ It is common to use a dict to collect frequency information,
+ where each added key matching a previously added key
+ increments the associated value. This is fine except for the
+ case of a thus-far-unique key not yet in the dictionary, which
+ has to be handled differently in order not to throw the
+ KeyError exception. Python dictionaries are touchier than Perl
+ hashes, and the initial entry cannot trigger a retrieval of a
+ null value; a KeyError exception is thrown. Thus, all
+ additions need to be handled in a way that eliminates the
+ KeyError on new key problem.
+ """
+ a = dict.get(key,0)
+ a += 1
+ dict[key] = a
+
+
+ def qlambda(self,n,q,pop):
+ """
+ qlambda measure at basis of all diversity metrics
+ Based on paper by Lou Jost
+
+ Inputs :
+ n, number of samples, if n==0 then do the whole population
+ q, the order, this is what frequencies are raised to
+ pop, the population to work on
+ """
+ popsize = len(pop)
+ if ((n > popsize) or (0 >= n)):
+ n = popsize
+
+ # Load xotypes with all the strings we want to analyze, either
+ # a sample or the whole population
+ # This assumes that n << popsize when n < popsize. There could be
+ # trouble with this is n is only slightly smaller than popsize,
+ # as it then is essentially trying to find a rare value by random
+ # search. To fix that, an alternate method within the first
+ # if clause should handle putting together the indices that would
+ # not be used, and then filling xotypes with the complementary
+ # set of indices.
+ # Initial workaround: limit restricted sample case to less than
+ # half the total population. This should keep the efficiency
+ # reasonably high.
+ if (n < (popsize * 0.5)): # Sample point randomly without replacement
+
+ ndx = -1 # Initial assignment should throw an error if used
+ xotypes = {} # Clear the temporary dictionary for genotype or phenotype
+ ndxs = {} # Clear the temporary dictionary of indices
+
+ for ii in range(n): # Find an unused index for every sample point
+ done = 0 # Initialize control flag for index selection
+
+ while (0 == done): # Repeat until we have an unused index
+ ndx = random.randrange(n) # Pick a candidate randomly
+ a = ndxs.get(ndx,0) # Has it already been picked?
+
+ if (0 == a): # New index, accept it
+ done = 1 # Flag to stop the while loop
+
+ self.addToDictWithIncrement(xotypes,pop[ndx]) # Add the genotype/phenotype to the dict
+ self.addToDictWithIncrement(ndxs,ndx) # Add the index to the used index dict
+ else:
+ xotypes = {} # Clear the temporary dict
+ for ii in pop: # Repeat for every entry in the population
+ self.addToDictWithIncrement(xotypes,ii) # Add to the dict
+
+ # Now the strings to analyze are in xotypes, so do the analysis
+ psum = 0.0
+ # Try it with a list completion
+ psum = math.sum([(v / n) ** q for k, v in xotypes.iteritems()])
+
+ return((psum,n))
+
+
+ def base_diversity(self,pop):
+ """
+ base_diversity
+
+ This calculates the diversity described as "gene diversity" in email
+ on Avida-ED capability.
+
+ For each base, calculate h' on the frequencies of bases seen among all
+ members of the population.
+ """
+ n = len(pop) # Find the total population size
+ #print "len(pop) = %d" % (n)
+
+ # Estimate upper bound on length of genome
+ bc = len(pop[0]) * 1 # Factor of 1 assumes all strings are the same length
+
+ hs = [] # Clear the h' array
+ for ii in range(bc): # For each base
+ # print "ii = %d" % (ii)
+ basecnt = {} # Clear the base counting dict
+ basen = 0 # Clear the counter for number of samples
+
+ for jj in range(n): # For every member of the population
+ # Only process if the length is right
+ if (bc <= len(pop[jj])):
+ #print "pop[%d][%d], pop[%d] = %s" % (jj,ii,jj,pop[jj])
+ #print "jj = %d, len(%s) = %d, char[%d] = %s" % (jj,pop[jj],len(pop[jj]),ii,pop[jj][ii])
+ #print "continuing"
+ self.addToDictWithIncrement(basecnt,pop[jj][ii]) # Increment a counter for each base found
+ basen += 1 # Increment the count of bases
+
+ # Initialize temporary variables
+ psum2 = 0.0
+ pf = 0.0
+ pf2 = 0.0
+ h = 0.0
+
+ for kk in basecnt: # For every different base observed
+ pf = (basecnt[kk] * 1.0) / (basen * 1.0) # Calculate the frequency of the base
+ pf2 = pf * pf # Calculate the squared frequency
+ psum2 += pf2 # Add to a running sum of the squared frequencies
+ h = 1.0 - psum2 # Find h' for this base as 1 - sum of squared frequencies
+ hs.append(h) # Save h' in array
+
+ hhat = 0.0 # Initialize the whole-string H estimate
+ for ii in hs: # For all the h's
+ hhat += ii # Add to a sum
+ hhat = hhat / bc # Take the average h' per base
+
+ #print "hhat = %7.5f, basen = %d" % (hhat,basen)
+
+ return(hhat) # Return the estimated h' per base
+
+ def tide_diversity(self,pop,s):
+ """
+ tide_diversity
+
+ This calculates the diversity measure described as "nucleotide
+ diversity" in email on Avida-ED capability.
+
+ This compares pairs of Avidians and calculates h' based on the
+ scaled proportion of differences between the Avidians.
+
+ Inputs:
+ pop : array of strings representing genotypes, phenotypes, or whatever.
+ s : sample size, 0 = whole population, 0.0 < s < 1.0 is a proportion, otherwise an absolute number of samples
+ """
+
+ popsize = len(pop)
+ totalsamples = ((popsize * popsize) - popsize) * 0.5 # Triangular non-identical pairs
+ pcnt = 0
+ dcsum = 0.0
+
+ if (s == 0):
+ """
+ Do the whole population.
+ """
+ #print "tide_diversity: whole population"
+ for ii in range(len(pop)):
+ for jj in range(len(pop)):
+ if (ii < jj):
+ pcnt += 1
+ # print "Getting diffs for $pop[$ii] and $pop[$jj]\n"
+ (dc,dm) = self.ndiffs(pop[ii],pop[jj])
+ dcsum += dc / len(pop[ii])
+
+ else:
+
+ pairs = {} # Clear the pairs dict
+ if (1.0 <= s):
+ """
+ Sample a specific number of pairs chosen randomly.
+ """
+ samples = int(min(s,totalsamples,popsize))
+ #print "tide_diversity: specific sample of population = %d" % (samples)
+ else:
+ """
+ Sample a fraction of the available pairs.
+ """
+
+ tsamp = s * totalsamples
+ samples = int(min(max(s * totalsamples,1),popsize))
+ #print "totalsamples=%d, proportion=%7.5f, intermediate=%7.5f, samples=%d" % (totalsamples,s,tsamp,samples)
+ #print "tide_diversity: proportion of population = %d" % (samples)
+ if (samples < totalsamples):
+ #print "samples = " + str(samples) + ",totalsamples = " + str(totalsamples)
+ #print "finding %d samples out of " % (samples) + str(totalsamples)
+ for ii in range(samples):
+ # Find an unexamined pair
+ done = 0
+ while (0 == done):
+ r1 = random.randrange(popsize)
+ r2 = random.randrange(popsize)
+
+ if (r1 != r2):
+ a = min(r1,r2)
+ b = max(r1,r2)
+ # Are those actual values in the population?
+ if (0 < min(len(pop[a]),len(pop[b]))):
+ k = "%d;%d" % (a,b)
+ self.addToDictWithIncrement(pairs,k)
+ if (1 == pairs[k]):
+ done = 1
+
+ pcnt += 1
+ # print "Getting diffs for $pop[$ii] and $pop[$jj]\n"
+ (dc,dm) = self.ndiffs(pop[a],pop[b])
+ dcsum += (dc * 1.0) / (len(pop[a]) * 1.0)
+ #print "difference count = %d, dcsum = %7.5f" % (dc,dcsum)
+
+ if (0 < pcnt):
+ ave_pi = dcsum / (pcnt * 1.0)
+ else:
+ ave_pi = 0.0
+ return(pcnt,ave_pi) # Return the number of pairs and the average
+
+ def shannon_via_q(self,n,q,pop):
+ h = 0.0
+ res = self.qlambda(n,q,pop)
+ return((n,h))
+
+
+
+ def shannon_mf(self,aos,lnbase):
+ """
+ shannon_mf
+ This method finds the Shannon diversity measure H based on the
+ machine formula provided by Lloyd et al. 1968.
+
+ Input: aos = an array of strings
+ All needed properties are extracted from those found in the array of
+ strings provided.
+ """
+ # H' = (c / N) * (log(N!) - sum(log(n_i)))
+
+ # Set c as the conversion factor to change the logarithm base
+ c = lnbase
+ # Find N as the number of strings in aos
+
+ # Collect the frequencies of appearance of each non-empty string
+ # Do this by setting up a temporary dictionary
+ mydict = {} # Clear the temporary dict
+
+ N = 0 # Initialize N
+ for ii in aos: # For every string in the array/list
+ if ("" != ii): # If the string is non-empty
+ # print "adding %s to dict" % (ii) # Debug output
+ self.addToDictWithIncrement(mydict,ii) # Add it to the frequency-tracking dict
+ N += 1 # Increment the string count
+
+ # print "N = %d" % (N) # Debug output
+
+ # Now sum up the individual frequency data
+ # This could require taking the factorial of a very large number,
+ # so use an approximation if the result will be very large
+ thesum = 0.0;
+ #for key in range(**mydict):
+ # value = mydict{key}
+ # thesum += math.log(self.factorial(value))
+
+ # Get the sum via list comprehension
+ # thesum = sum(math.log(self.factorial(elem)) for elem in mydict.values)
+
+
+ # print "summing up" # Debug output
+ if (0): # So don't do it this way
+ for k, v in mydict.iteritems():
+ thesum += math.log(self.factorial(v))
+ theh = (lnbase / N) * (math.log(self.factorial(N)) - thesum)
+
+ # Old school
+ p = 0.0 # Initialize frequency
+ psum = 0.0 # Initialize sum of frequencies
+ for k, v in mydict.iteritems(): # For every string that appears
+ # $p = $gens{$_} / $popsize;
+ # $psum += $p * log($p);
+ p = float(v) / N # Calculate the frequency
+ psum += p * math.log(p) # Add to the summation
+
+ theh = - psum # Negate to make it H'
+
+ ens = math.exp(theh) # Get effective number of species per Jost
+
+ return ((theh,N,ens))
+
+ def ginisimpson(self,aos):
+ """
+ ginisimpson
+
+
+sub find_div2 {
+ local(@pop) = @_;
+ local($_,$ii,$jj,$pcnt);
+
+ $pcnt = 0;
+ $dcsum = 0.0;
+ for ($ii = 0; $ii < $#pop; $ii++) {
+ for ($jj = $ii+1; $jj <= $#pop; $jj++) {
+ if ($ii < $jj) {
+ $pcnt++;
+ # print "Getting diffs for $pop[$ii] and $pop[$jj]\n";
+ ($dc,$dm) = &ndiffs($pop[$ii],$pop[$jj]);
+ $dcsum += $dc / length($pop[$ii]);
+ }
+ }
+ }
+
+ $pi = $dcsum / $pcnt;
+ print "$pi = $dcsum / $pcnt;\n";
+
+ return($pi,$pcnt);
+}
+ """
+ pcnt = 0
+ dcsum = 0.0
+ for ii in range(aos):
+ for jj in range(aos):
+ if (jj < ii):
+ pcnt += 1
+ # Count differences between two strings
+ (dc, dm) = self.ndiffs(aos[ii],aos[jj])
+
+ # Normalize for string length and sum
+ dcsum = dc / min(len(aos[ii]),len(aos[jj]))
+
+ pi = dcsum / pcnt
+
+ # multiple values being returned, so use a tuple
+ return((pi,pcnt))
+
+
+ def ginisimpson_timed(self,aos):
+ """
+ ginisimpson_timed
+
+sub find_div2_timed_dt {
+ local($seconds, at pop) = @_;
+ local($_,$ii,$jj,$pcnt);
+
+ #$t0 = DateTime->now;
+
+ $popsize = $#pop + 1;
+ $pcnt = 0;
+ $dcsum = 0.0;
+ undef(%pairs);
+ $td = 0.0;
+ do {
+ # Get the population indices for a pair randomly
+ $trycnt = 0;
+
+ $bad = 0;
+ do {
+ $ok = 0;
+ $r1 = int(rand($popsize));
+ $r2 = int(rand($popsize));
+ unless ($r1 == $r2) {
+ $ii = &min($r1,$r2);
+ $jj = &max($r1,$r2);
+ $key = join(";",$ii,$jj);
+ unless (defined $pairs{$key}) {
+ $ok = 1;
+ }
+ }
+ if ((0.4 * $popsize) < $trycnt++) {
+ $bad = 1;
+ }
+ } until ($ok || $bad);
+
+ # print "$key\n";
+ if ($bad) {
+ $pi = $dcsum / $pcnt;
+ # print "$td: $pi = $dcsum / $pcnt;\n";
+
+ return($pi,$pcnt);
+ }
+
+ # Compare them
+ $pcnt++;
+ ($dc,$dm) = &ndiffs($pop[$ii],$pop[$jj]);
+ $dcsum += $dc / length($pop[$ii]);
+
+ # Are we out of time?
+ #$t1 = DateTime->now;
+ #$td = $t1 - $t0;
+ #$tds = $td->offset;
+ $tds = $pcnt / 16000;
+ #print "td = $tds, seconds = $seconds\n";
+ } while ($seconds > $tds);
+
+ #print "Out of while loop\n";
+
+ $pi = $dcsum / $pcnt;
+ print "$tds: $pi = $dcsum / $pcnt;\n";
+
+ return($pi,$pcnt);
+}
+ """
+
+
+ pass
+
+
+
+
Modified: branches/developers/avida-edward/source/python/AvidaGui2/pyEduWorkspaceCtrl.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyEduWorkspaceCtrl.py 2009-08-04 03:26:21 UTC (rev 3356)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyEduWorkspaceCtrl.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -43,10 +43,10 @@
# filter function:
plugins = filter(lambda f: (os.path.splitext(f)[1] == '.ae_plugin'), names)
- #print "plugin_visitor: arg:", arg
- #print "plugin_visitor: dirname:", dirname
- #print "plugin_visitor: names:", names
- #print "plugin_visitor: plugins:", plugins
+ print "plugin_visitor: arg:", arg
+ print "plugin_visitor: dirname:", dirname
+ print "plugin_visitor: names:", names
+ print "plugin_visitor: plugins:", plugins
# Save the system path as is, so it can be restored later.
sys_path = sys.path
@@ -56,7 +56,7 @@
for plugin in plugins:
# Put together the path to this plugin
plugin_path = os.path.abspath(os.path.join(dirname, plugin))
- #print "plugin_visitor: plugin_path:", plugin_path
+ print "plugin_visitor: plugin_path:", plugin_path
# Alter the system path temporarily
sys.path = [plugin_path] + sys_path
@@ -75,7 +75,7 @@
# into the Avida instance
p.construct(edu_workspace_ctrl.m_session_mdl)
- #print "plugin_visitor: p:", p
+ print "plugin_visitor: p:", p
except Exception, details:
# Handle exceptions so that all the plugins can be tried
print "Exception:", details
Modified: branches/developers/avida-edward/source/python/AvidaGui2/pyFreezerCtrl.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyFreezerCtrl.py 2009-08-04 03:26:21 UTC (rev 3356)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyFreezerCtrl.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -269,6 +269,8 @@
self.m_session_mdl.m_session_mdtr.emit(PYSIGNAL("freezerItemsSelectedSig"),
("",))
+ self.m_session_mdl.m_session_mdtr.emit(PYSIGNAL("refreshSubDishList"), ())
+
# if mouse is pressed on list item prepare its info to be dragged
def pressed_itemSlot(self, item):
@@ -354,6 +356,7 @@
descr("item.text(0) is: ",str(item.text(0)))
descr("file_name is", file_name)
+ self.m_session_mdl.m_session_mdtr.emit(PYSIGNAL("statusBarMessageSig"), ("Large dishes may take a few minutes to process. Be patient.",))
self.m_session_mdl.m_session_mdtr.emit(PYSIGNAL("doDefrostDishSig"),
(item.text(0), thawed_item,))
descr("BDB -- item.text(0) = " + str(item.text(0)))
@@ -371,6 +374,7 @@
short_name = short_name[:-5]
in_file_name = os.path.join(in_file_name, "petri_dish")
thawed_item = pyReadFreezer(in_file_name)
+ self.m_session_mdl.m_session_mdtr.emit(PYSIGNAL("statusBarMessageSig"), ("Large dishes may take a few minutes to process. Be patient.",))
self.m_session_mdl.m_session_mdtr.emit(PYSIGNAL("doDefrostDishSig"),
(short_name, thawed_item,))
self.m_session_mdl.m_session_mdtr.emit(PYSIGNAL("freezerItemDoubleClicked"),
@@ -405,6 +409,7 @@
file_name = str(item.text(0)) + ".empty"
elif str(top_level.text(0)).startswith(" Populated Dish"):
file_name = str(item.text(0)) + ".full"
+ print "pyFreezerCtrl : rebuilding filename %s" % (file_name)
elif str(top_level.text(0)).startswith(" Organism"):
file_name = str(item.text(0)) + ".organism"
file_name = os.path.join(self.m_session_mdl.m_current_freezer, file_name)
Added: branches/developers/avida-edward/source/python/AvidaGui2/pyGridMaster.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyGridMaster.py (rev 0)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyGridMaster.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+
+### pyGridMaster
+# Created 2009/02/03 by Wesley R. Elsberry
+#
+# Python module to handle client/server grid transformations in Avida-ED plugin.
+# The server must allow clients to contribute dishes.
+
+
+# class pySuperDish:
+ ### Class to handle multiple contributed dishes
+
+class Grids:
+ def __init__(self,sx=5,sy=5,cx=60,cy=60):
+ # Set default values
+ self.serverGridXDefault = sx
+ self.serverGridYDefault = sy
+ self.clientGridXDefault = cx
+ self.clientGridYDefault = cy
+ self.serverGridExists = False
+
+ # Grid transformations
+ # Generic methods of mapping client dishes of arbitrary size together
+ # into one server dish, and for mapping back to client dishes
+ #
+
+ def clientCell2ServerCell(self,inx,iny,igx,igy,snx,sny,sgc):
+ """
+ Client dish of size (snx,sny) with cell sgc maps to a server dish cell igc
+ given server dish grid size of (inx,iny) and sub-dish of (igx,igy)
+
+ Inputs:
+ inx = # of subdishes in a row
+ iny = # of subdishes in a column
+ igx = index in row of multidish placement for subdish (base 1)
+ igy = index in column of multidish placement for subdish (base 1)
+ snx = # of cells in row of subdish
+ sny = # of cells in column of subdish
+ sgc = cell index in subdish
+
+ Output:
+ igc = cell index in multidish (base 0)
+ """
+ irw = inx * snx # server grid row width
+ iro = (igx-1) * snx # server grid row offset
+ sgco = sgc / snx # client grid column offset, integer division
+ sgro = sgc % snx # client grid row offset
+ ico = sgc / irw # server grid column offset, integer division
+ igc = (sgro + iro) + (sgco * irw) + (((igy - 1) * irw) * sny)
+ # Now get ix, iy from grid cell
+ ix = igc % irw
+ iy = igc / irw
+ return igc, ix, iy
+
+ def serverCell2ClientCell(self,inx,iny,snx,sny,igc):
+ """
+ Server grid cell igc in dish size (inx,iny) of sub-grids of size (snx,sny)
+ maps back to client grid (sgx,sgy) and client cell (sgc)
+
+ Inputs:
+ inx = # of subdishes in a row
+ iny = # of subdishes in a column
+ snx = # of cells in row of subdish
+ sny = # of cells in column of subdish
+ igc = cell index in multidish
+
+ Output:
+ list containing
+ sgc = cell index in subdish (base 0)
+ sgx = index in row of subdish (base 0)
+ sgy = index in column of subdish (base 0)
+ """
+ # print "serverCell2ClientCell(%s, %s, %s, %s, %s)" % (inx, iny, snx, sny, igc)
+ irw = inx * snx # server grid row width
+ igx = ((igc % irw) / snx) + 1 # Needs integer division
+ igy = (igc / (irw * sny)) + 1 # Needs integer division
+ sgx = ((igc % irw) % snx) + 1 #
+ sgy = ((igc / irw) + 1) - ((igy - 1) * sny)
+ sgc = ((sgy - 1) * snx) + (sgx - 1)
+ # Which subdish did this come from?
+ sgpos = ((igy - 1) * inx) + igx - 1
+ ccelldata = [sgc, sgx, sgy, igx, igy, sgpos]
+ return ccelldata
+
+
+ def makeServerGrid(self, XSize, YSize):
+ if (self.serverGridExists):
+ # Error; redundant call to make the server grid, ignore
+ return -1
+ # Set up server grid
+ self.serverGridExists = True
+
+
+"""
+Self-test
+"""
+if __name__ == "__main__":
+ sd_nrow = 4
+ sd_ncol = 4
+ sd_rowsize = 30
+ sd_colsize = 30
+ mygrid = Grids(sd_nrow,sd_ncol,sd_rowsize,sd_colsize)
+
+ mdcell = 1
+ sdinfo = mygrid.serverCell2ClientCell(sd_nrow,sd_ncol,sd_rowsize,sd_colsize,mdcell)
+ print "%s = mygrid.serverCell2ClientCell(%s,%s,%s,%s,%s)" % (sdinfo,sd_nrow,sd_ncol,sd_rowsize,sd_colsize,mdcell)
+
+ mdcell = 2 + sd_rowsize * 1
+ sdinfo = mygrid.serverCell2ClientCell(sd_nrow,sd_ncol,sd_rowsize,sd_colsize,mdcell)
+ print "%s = mygrid.serverCell2ClientCell(%s,%s,%s,%s,%s)" % (sdinfo,sd_nrow,sd_ncol,sd_rowsize,sd_colsize,mdcell)
+
+ mdcell = 3 + sd_rowsize * 2
+ sdinfo = mygrid.serverCell2ClientCell(sd_nrow,sd_ncol,sd_rowsize,sd_colsize,mdcell)
+ print "%s = mygrid.serverCell2ClientCell(%s,%s,%s,%s,%s)" % (sdinfo,sd_nrow,sd_ncol,sd_rowsize,sd_colsize,mdcell)
Added: branches/developers/avida-edward/source/python/AvidaGui2/pyMDMkEnv.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyMDMkEnv.py (rev 0)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyMDMkEnv.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -0,0 +1,371 @@
+"""
+pyMkEnv.py
+
+Module to assist in writing out Avida environment files for Multi-Dish runs.
+"""
+
+import pyGridMaster
+
+class MkEnv():
+ """
+ MkEnv
+
+ Class with methods for environment-writing
+ """
+
+ def __init__(self, mdx, mdy, sdx, sdy):
+ # Number of sub-dishes in a row
+ self.mdx = mdx
+ # Number of sub-dishes in a column
+ self.mdy = mdy
+ # Number of cells in a sub-dish row
+ self.sdx = sdx
+ # Number of cells in a sub-dish column
+ self.sdy = sdy
+
+ self.resources = ('not', 'nand', 'and', 'orn', 'oro', 'andn', 'nor', 'xor', 'equ', )
+ self.reactions = ('NOT', 'NAND', 'AND', 'ORN', 'ORO', 'ANDN', 'NOR', 'XOR', 'EQU', )
+
+ self.grid = pyGridMaster.Grids(self.mdx,self.mdy,self.sdx,self.sdy)
+
+ # Dictionary of tasks, resources, reactions, and rewards
+ self.rrr = {'not':('not','NOT',1, ),
+ 'nand':('nand','NAND',1, ),
+ 'and':('and','AND',2, ),
+ 'orn':('orn','ORN',2, ),
+ 'or':('or','OR',3, ),
+ 'andn':('andn','ANDN',3, ),
+ 'nor':('nor','NOR',4, ),
+ 'xor':('xor','XOR',4, ),
+ 'equ':('equ','EQU',5, )
+ }
+
+ # Need to order the tasks
+ self.tasks = ('not', 'nand', 'and', 'orn', 'or', 'andn', 'nor', 'xor', 'equ', )
+
+ def mkTemplate(self,envTempName):
+ """
+ mkTemplate
+
+ Method to output an enviroment file suitable for processing to
+ a specific set of sub-dish settings. This sets up
+ spatially-defined resources that span the entire multi-dish,
+ but specifies each resource-subgrid pair separately.
+
+ Implementation: Each sub-dish gets its own resource/reaction/task definition.
+ """
+
+ f_env = open(envTempName, 'w')
+
+ f_env.write("###############\n")
+ f_env.write("#\n")
+ f_env.write("# Multi-Dish environment template file\n")
+ f_env.write("#\n")
+ f_env.write("###############\n\n")
+
+ # List of resources
+
+ # All logic-9 resources get an entry per sub-dish, with coordinates
+ # defined to fit the boundary of the sub-dish.
+
+ print "Setting resources"
+ for mx in range(1,self.mdx+1):
+ for my in range(1,self.mdy+1):
+
+ #if (((3 == mx) and (3 == my)) or ((4 == mx) and (4==my))):
+ #if ((3 == mx) and (3 != my)):
+ if (1):
+ #if (my < (self.mdy - 1)):
+ # Find upper left and lower right grid cells for the
+ # subdish in the multi-dish
+
+ mdcul,mdulx,mduly = self.grid.clientCell2ServerCell(self.mdx,self.mdy,mx,my,self.sdx,self.sdy,0)
+ mdclr,mdlrx,mdlry = self.grid.clientCell2ServerCell(self.mdx,self.mdy,mx,my,self.sdx,self.sdy,self.sdx*self.sdy - 1)
+
+ print "UL %s ULX %s ULY %s LR %s LRX %s LRY %s" % (mdcul, mdulx, mduly, mdclr, mdlrx, mdlry)
+ #mdlry /= 2
+ #print "UL %s ULX %s ULY %s LR %s LRX %s LRY %s" % (mdcul, mdulx, mduly, mdclr, mdlrx, mdlry)
+
+ inflow = self.sdx * self.sdy * 1.0
+ outflow = 0.1
+
+ for ii in self.tasks:
+ tstr = "RESOURCE %s%s%s%s" + \
+ ":initial=0.00001" + \
+ ":geometry=torus" + \
+ ":inflow=%s" + \
+ ":outflow=%s" + \
+ ":inflowx1=%s" + \
+ ":inflowx2=%s" + \
+ ":inflowy1=%s" + \
+ ":inflowy2=%s" + \
+ ":outflowx1=%s" + \
+ ":outflowx2=%s" + \
+ ":outflowy1=%s" + \
+ ":outflowy2=%s" + \
+ ":xgravity=0" + \
+ ":ygravity=0" + \
+ ":xdiffuse=0" + \
+ ":ydiffuse=0\n"
+ f_env.write(tstr % ("res_",self.rrr[ii][0],mx,my,
+ inflow,outflow,
+ mdulx,mdlrx,
+ mduly,mdlry,
+ mdulx,mdlrx,
+ mduly,mdlry))
+
+ f_env.write("\n")
+
+ f_env.write("\n\n")
+
+ for mx in range(1,self.mdx+1):
+ for my in range(1,self.mdy+1):
+
+ # if ((3 == mx) and (3 == my)):
+ # if (((3 == mx) and (3 == my)) or ((4 == mx) and (4==my))):
+ #if ((3 == mx) and (3 != my)):
+ #if (1):
+ if (my < (self.mdy - 1)):
+ for ii in self.tasks:
+ tstr = "REACTION %s%s%s%s %s process" + \
+ ":resource=%s%s%s%s" + \
+ ":value=1.0" + \
+ ":max=1.0" + \
+ ":min=0.001" + \
+ ":frac=0.5:" + \
+ "product=%s%s%s%s" + \
+ ":conversion=1.0:" + \
+ "type=pow" + \
+ " requisite" + \
+ ":max_count=1\n"
+ f_env.write(tstr % ("REA_",self.rrr[ii][1],mx,my,
+ self.rrr[ii][0],
+ "res_",self.rrr[ii][0],mx,my,
+ "res_",self.rrr[ii][0],mx,my))
+
+ f_env.write("\n")
+
+ f_env.write("\n\n")
+ f_env.close()
+
+ def mkEnvFile(self,envName,sgv):
+ """
+ mkTemplate
+
+ Method to output an enviroment file specifying a set of
+ sub-dish settings. This sets up spatially-defined resources
+ that span the entire multi-dish, but specifies each
+ resource-subgrid pair separately.
+
+ Inputs:
+ envName : filename of environment configuration file
+ sgv : dictionary with the task information
+ """
+
+ f_env = open(envTempName, 'w')
+
+ f_env.write("###############\n")
+ f_env.write("#\n")
+ f_env.write("# Multi-Dish environment template file\n")
+ f_env.write("#\n")
+ f_env.write("###############\n\n")
+
+ # List of resources
+ # All logic-9 resources get an entry.
+ endidx = self.mdx * self.sdx - 1
+ for ii in self.rrr:
+ tstr = "RESOURCE %s" + \
+ ":initial=0.1" + \
+ ":geometry=torus" + \
+ ":inflow=1.0" + \
+ ":outflow=0.0" + \
+ ":inflowx1=0" + \
+ ":inflowx2=%s" + \
+ ":inflowy1=0" + \
+ ":inflowy2=%s" + \
+ ":outflowx1=0" + \
+ ":outflowx2=%s" + \
+ ":outflowy1=0" + \
+ ":outflowy2=%s" + \
+ ":xgravity=0" + \
+ ":ygravity=0" + \
+ ":xdiffuse=0" + \
+ ":ydiffuse=0\n"
+ f_env.write(tstr % (self.rrr[ii][0],endidx,endidx,endidx,endidx))
+
+ f_env.write("\n\n")
+
+ for ii in self.rrr:
+ tstr = "REACTION %s %s process" + \
+ ":value=1.0" + \
+ ":max=1.0" + \
+ ":min=0.001" + \
+ ":frac=0.5:" + \
+ "product=%s" + \
+ ":conversion=1.0:" + \
+ "type=pow" + \
+ " requisite" + \
+ ":max_count=1\n"
+ f_env.write(tstr % (self.rrr[ii][1],self.rrr[ii][0],self.rrr[ii][0]))
+
+ f_env.write("\n\n")
+
+ # Cell section. Write out complete set of resources and ranges.
+ for mx in range(1,self.mdx+1):
+ for my in range(1,self.mdy+1):
+ sdkey = ','.join(mx,my)
+ print sdkey
+
+ f_env.write("\n# Sub-dish [%s,%s]\n" % (mx,my))
+ for ii in self.sgv:
+ f_env.write("CELL %s:" % (ii))
+
+ sdrange = []
+ for jj in range(self.sdy):
+ mdc = self.grid.clientCell2ServerCell(self.mdx,self.mdy,mx,my,self.sdx,self.sdy,jj * self.sdx)
+ subrange = "%s..%s" % (mdc, mdc + self.sdx - 1)
+ sdrange.append(subrange)
+ thisrange = ",".join(sdrange)
+ f_env.write(thisrange)
+
+ f_env.write(":initial=1.0:inflow=0.0:outflow=0.0\n")
+
+ f_env.close()
+
+ def mkMDTemplate(self,envTempName,mdset):
+ """
+ mkMDTemplate
+
+ Method to output an enviroment file suitable for processing to
+ a specific set of sub-dish settings. This sets up
+ spatially-defined resources that span the entire multi-dish,
+ but specifies each resource-subgrid pair separately.
+
+ Implementation: Each sub-dish gets its own resource/reaction/task definition.
+ """
+ print "pyMDMkEnv.mkMDTemplate()"
+
+ # Base-0 or Base-1 for position encoding in keys?
+ base1 = False # Use Base-0, not Base-1
+ # base1 = True # Use Base-1, not Base-0
+
+ print mdset
+
+ f_env = open(envTempName, 'w')
+
+ f_env.write("###############\n")
+ f_env.write("#\n")
+ f_env.write("# Multi-Dish environment file\n")
+ f_env.write("#\n")
+ f_env.write("###############\n\n")
+
+ # List of resources
+
+ # All logic-9 resources get an entry per sub-dish, with coordinates
+ # defined to fit the boundary of the sub-dish.
+
+ print "Setting resources"
+ for mx in range(1,self.mdx+1):
+ for my in range(1,self.mdy+1):
+
+ #if (((3 == mx) and (3 == my)) or ((4 == mx) and (4==my))):
+ #if ((3 == mx) and (3 != my)):
+ if (1):
+ #if (my < (self.mdy - 1)):
+ # Find upper left and lower right grid cells for the
+ # subdish in the multi-dish
+
+ mdcul,mdulx,mduly = self.grid.clientCell2ServerCell(self.mdx,self.mdy,mx,my,self.sdx,self.sdy,0)
+ mdclr,mdlrx,mdlry = self.grid.clientCell2ServerCell(self.mdx,self.mdy,mx,my,self.sdx,self.sdy,self.sdx*self.sdy - 1)
+
+ print "UL %s ULX %s ULY %s LR %s LRX %s LRY %s" % (mdcul, mdulx, mduly, mdclr, mdlrx, mdlry)
+ #mdlry /= 2
+ #print "UL %s ULX %s ULY %s LR %s LRX %s LRY %s" % (mdcul, mdulx, mduly, mdclr, mdlrx, mdlry)
+
+ inflow = self.sdx * self.sdy * 1.0
+ outflow = 0.1
+
+ for ii in self.tasks:
+ tstr = "RESOURCE %s%s%s%s" + \
+ ":initial=0.00001" + \
+ ":geometry=torus" + \
+ ":inflow=%s" + \
+ ":outflow=%s" + \
+ ":inflowx1=%s" + \
+ ":inflowx2=%s" + \
+ ":inflowy1=%s" + \
+ ":inflowy2=%s" + \
+ ":outflowx1=%s" + \
+ ":outflowx2=%s" + \
+ ":outflowy1=%s" + \
+ ":outflowy2=%s" + \
+ ":xgravity=0" + \
+ ":ygravity=0" + \
+ ":xdiffuse=0" + \
+ ":ydiffuse=0\n"
+ # Set inflow and outflow differently based on whether the resource is "YES" in MD dict
+ if (base1):
+ # Base-1 for x,y position
+ currkey = "RES_%s%s_%s" % (mx,my,str(ii).upper())
+ else:
+ # Base-0 for x,y position
+ currkey = "RES_%s%s_%s" % (mx-1,my-1,str(ii).upper())
+ # Check for reward of this task in this subdish
+ # Two steps: does the key exist? Then, what is the value?
+ if (mdset.has_key(currkey) and ("YES" == mdset[currkey])):
+ print "currkey YES : %s" % (currkey)
+ inflow = self.sdx * self.sdy * 1.0
+ outflow = 0.1
+ else:
+ print "currkey NO : %s" % (currkey)
+ inflow = self.sdx * self.sdy * 0.000001
+ outflow = 0.9
+
+ f_env.write(tstr % ("res_",self.rrr[ii][0],mx,my,
+ inflow,outflow,
+ mdulx,mdlrx,
+ mduly,mdlry,
+ mdulx,mdlrx,
+ mduly,mdlry))
+
+ print tstr % ("res_",self.rrr[ii][0],mx,my,
+ inflow,outflow,
+ mdulx,mdlrx,
+ mduly,mdlry,
+ mdulx,mdlrx,
+ mduly,mdlry)
+
+
+ f_env.write("\n")
+
+ f_env.write("\n\n")
+
+ for mx in range(1,self.mdx+1):
+ for my in range(1,self.mdy+1):
+
+ if (1):
+ for ii in self.tasks:
+ tstr = "REACTION %s%s%s%s %s process" + \
+ ":resource=%s%s%s%s" + \
+ ":value=1.0" + \
+ ":max=1.0" + \
+ ":min=0.001" + \
+ ":frac=0.5:" + \
+ "product=%s%s%s%s" + \
+ ":conversion=1.0:" + \
+ "type=pow" + \
+ " requisite" + \
+ ":max_count=1\n"
+ f_env.write(tstr % ("REA_",self.rrr[ii][1],mx,my,
+ self.rrr[ii][0],
+ "res_",self.rrr[ii][0],mx,my,
+ "res_",self.rrr[ii][0],mx,my))
+ print tstr % ("REA_",self.rrr[ii][1],mx,my,
+ self.rrr[ii][0],
+ "res_",self.rrr[ii][0],mx,my,
+ "res_",self.rrr[ii][0],mx,my)
+
+ f_env.write("\n")
+
+ f_env.write("\n\n")
+ f_env.close()
Added: branches/developers/avida-edward/source/python/AvidaGui2/pyMDSetupFormView.ui
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyMDSetupFormView.ui (rev 0)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyMDSetupFormView.ui 2009-08-05 16:45:50 UTC (rev 3357)
@@ -0,0 +1,493 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>md_setup_Form</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>md_setup_Form</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>801</width>
+ <height>648</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Multi-Dish</string>
+ </property>
+ <widget class="QTabWidget">
+ <property name="name">
+ <cstring>tabWidget2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>790</width>
+ <height>630</height>
+ </rect>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Multi-Dish Setup</string>
+ </attribute>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>setMDParams_groupBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>500</width>
+ <height>170</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Step 1: Set Multi-Dish Parameters</string>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>md_set_values_pushButton</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>129</y>
+ <width>117</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Set Values</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>md_values_textLabel</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>134</x>
+ <y>129</y>
+ <width>345</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>MD: </string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>md_name_textLabel</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>12</x>
+ <y>100</y>
+ <width>107</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Multi-Dish name</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>md_name_lineEdit</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>125</x>
+ <y>100</y>
+ <width>353</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>md-</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>sdy_textLabel</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>12</x>
+ <y>66</y>
+ <width>116</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>SubDishes / col</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>sdy_spinBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>134</x>
+ <y>66</y>
+ <width>116</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>4</number>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>sdx_textLabel</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>12</x>
+ <y>32</y>
+ <width>116</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>SubDishes / row</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>sdx_spinBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>134</x>
+ <y>32</y>
+ <width>116</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>4</number>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>sdnx_textLabel</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>258</x>
+ <y>32</y>
+ <width>155</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Grid Cells / SubDish row</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>sdnx_spinBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>419</x>
+ <y>32</y>
+ <width>59</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>30</number>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>sdny_textLabel</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>258</x>
+ <y>66</y>
+ <width>155</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Grid Cells / SubDish col</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>sdny_spinBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>419</x>
+ <y>66</y>
+ <width>59</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>30</number>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>generateMulti_Dish_groupBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>508</x>
+ <y>442</y>
+ <width>250</width>
+ <height>130</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Step 3. Generate Multi-Dish</string>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>md_generate_pushButton</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>22</x>
+ <y>58</y>
+ <width>200</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Generate Multi-Dish</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>setSubDishLayout_groupBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>170</y>
+ <width>500</width>
+ <height>420</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Step 2. Layout SubDishes</string>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout20</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>12</x>
+ <y>28</y>
+ <width>460</width>
+ <height>50</height>
+ </rect>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>sd_pick_textLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Choose SubDish</string>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>sd_pick_comboBox</cstring>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>sd_list_refresh_pushButton</cstring>
+ </property>
+ <property name="text">
+ <string>Refresh</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QTextEdit">
+ <property name="name">
+ <cstring>md_layout_textEdit</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>12</x>
+ <y>146</y>
+ <width>480</width>
+ <height>230</height>
+ </rect>
+ </property>
+ <property name="font">
+ <font>
+ <family>Courier New</family>
+ <bold>1</bold>
+ </font>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>sd_pos_in_md_textLabel</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>14</x>
+ <y>90</y>
+ <width>247</width>
+ <height>46</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Choose SubDish Position in Multi-Dish</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>sd_pos_in_md_spinBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>277</x>
+ <y>100</y>
+ <width>73</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>sd_add_pushButton</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>12</x>
+ <y>378</y>
+ <width>480</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Add SubDish To Multi-Dish Layout</string>
+ </property>
+ </widget>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Multi-Dish Statistics</string>
+ </attribute>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>MDRunStatistics_groupBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>760</width>
+ <height>280</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Run Statistics</string>
+ </property>
+ <widget class="QTextEdit">
+ <property name="name">
+ <cstring>MDRunStatistics_textEdit</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>20</y>
+ <width>760</width>
+ <height>260</height>
+ </rect>
+ </property>
+ <property name="font">
+ <font>
+ <family>Courier New</family>
+ <pointsize>11</pointsize>
+ </font>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>MDDiversity_groupBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>280</y>
+ <width>760</width>
+ <height>310</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Multi-Dish Diversity</string>
+ </property>
+ <widget class="QTextEdit">
+ <property name="name">
+ <cstring>MDDiversity_textEdit</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>-2</x>
+ <y>22</y>
+ <width>760</width>
+ <height>290</height>
+ </rect>
+ </property>
+ <property name="font">
+ <font>
+ <family>Courier New</family>
+ <pointsize>11</pointsize>
+ </font>
+ </property>
+ </widget>
+ </widget>
+ </widget>
+ </widget>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
Modified: branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_GraphCtrl.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_GraphCtrl.py 2009-08-04 03:26:21 UTC (rev 3356)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_GraphCtrl.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -77,6 +77,13 @@
self.m_graph_ctrl.setAxisAutoScale(QwtPlot.xBottom)
self.m_graph_ctrl.setAxisAutoScale(QwtPlot.yLeft)
+
+ # @WRE: attach a grid
+ self.m_graph_ctrl.m_grid = Qwt.QwtPlotGrid()
+ self.m_graph_ctrl.m_grid.attach(self.m_graph_ctrl)
+ self.m_graph_ctrl.m_grid.setPen(QPen(Qt.black, 0, Qt.DotLine))
+
+
self.m_graph_ctrl.replot()
def setAvidaSlot(self, avida):
Added: branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_MDView.ui
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_MDView.ui (rev 0)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_MDView.ui 2009-08-05 16:45:50 UTC (rev 3357)
@@ -0,0 +1,590 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>pyOnePop_MDView</class>
+<comment>
+Python:from pyOrgSquareCtrl import pyOrgSquareCtrl
+</comment>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>pyOnePop_MDView</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>19</x>
+ <y>0</y>
+ <width>334</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>400</height>
+ </size>
+ </property>
+ <property name="caption">
+ <string>pyOnePop_MDView</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox4</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>30000</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <family>Arial</family>
+ <pointsize>10</pointsize>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="title">
+ <string>Population Diversity</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Information on single highlighted organism from population</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox5</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <family>Arial</family>
+ <pointsize>10</pointsize>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="frameShape">
+ <enum>GroupBoxPanel</enum>
+ </property>
+ <property name="title">
+ <string>Population Statistics</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Information about the entire population of organisms in the petri dish</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout56</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel14_3_3_2_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <bold>0</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Population Size:</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>m_num_orgs</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <bold>0</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>-</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout64</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel14_3_3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>40</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <bold>0</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Avg. Fitness:</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6_2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>85</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>m_avg_fitness</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>3000</width>
+ <height>3000</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <bold>0</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>-</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout59</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel14_3_3_2_2_2_3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>40</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <bold>0</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Avg. Metabolic Rate:</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6_2_2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>m_avg_merit</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <bold>0</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>-</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout60</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel14_3_3_2_2_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>40</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <bold>0</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Avg. Gestation:</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6_2_2_2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>m_avg_gest</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <bold>0</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>-</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout62</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel14_3_3_2_2_2_4_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>40</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <bold>0</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Avg. Age (updates):</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6_2_2_2_3_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>m_avg_age</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <bold>0</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>-</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout61</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel14_3_3_2_2_2_4</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>40</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <bold>0</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6_2_2_2_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>m_avg_genome_length</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <bold>0</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
Modified: branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_PetriDishCtrl.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_PetriDishCtrl.py 2009-08-04 03:26:21 UTC (rev 3356)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_PetriDishCtrl.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -116,7 +116,7 @@
lineage_range = len(self.m_session_mdl.m_ancestors_dict)
non_normalized_index = int(label) + 1
normalized_index = float(non_normalized_index) / float(lineage_range)
- print "self.m_petri_dish_ctrl is: ", self.m_petri_dish_ctrl
+ # print "self.m_petri_dish_ctrl is: ", self.m_petri_dish_ctrl
a_sensible_color = self.m_petri_dish_ctrl.m_color_lookup_functor(normalized_index)
#the following ugly code is brought to you by the fact that I can't delete objects
@@ -236,6 +236,10 @@
if (e.source is self):
return
+ self.m_session_mdl.m_session_mdtr.emit(PYSIGNAL("statusBarMessageSig"), ("Large dishes may take a few minutes to process. Be patient.",))
+ self.repaint()
+
+
current_page = self.m_petri_dish_widget_stack.visibleWidget()
current_page_int = self.m_petri_dish_widget_stack.id(current_page)
@@ -311,6 +315,9 @@
def DefrostSlot(self, dish_name, petri_dict):
descr()
+ self.m_session_mdl.m_session_mdtr.emit(PYSIGNAL("statusBarMessageSig"), ("Large dishes may take a few minutes to process. Be patient.",))
+ self.repaint()
+
self.m_session_mdl.m_session_mdtr.emit(PYSIGNAL("raisePopViewSig"),())
# if self.isVisible():
@@ -345,6 +352,7 @@
else:
return
+
self.RenameDishSlot(dish_name)
self.finishedPetriDish = False
self.m_session_mdl.m_session_mdtr.emit(PYSIGNAL("FillDishSig"),
@@ -358,6 +366,9 @@
self.m_session_mdl.m_session_mdtr.emit(
PYSIGNAL("restartPopulationSig"), (self.m_session_mdl, ))
+ self.m_session_mdl.m_session_mdtr.emit(
+ PYSIGNAL("refreshSubDishList"), ())
+
def finishedPetriDishSlot(self):
descr()
Modified: branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_StatsCtrl.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_StatsCtrl.py 2009-08-04 03:26:21 UTC (rev 3356)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyOnePop_StatsCtrl.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -8,6 +8,8 @@
from pyOnePop_StatsView import pyOnePop_StatsView
from pyOrgSquareCtrl import pyOrgSquareCtrl
import os
+from pyGridMaster import Grids
+from AvidaCore import cConfig
class pyOnePop_StatsCtrl(pyOnePop_StatsView):
@@ -80,7 +82,9 @@
def avidaUpdatedSlot(self):
# print "pyOnePop_StatsCtrl.avidaUpdatedSlot() called.\n"
stats = self.m_avida.m_population.GetStats()
-
+
+ self.m_session_mdl.md_runstats["AVERAGES"] = {}
+
#STATISTICS WINDOW
string_output_length = 7
@@ -95,6 +99,8 @@
avg_fitness = "%.2g" %(stats.GetAveFitness())
self.m_avg_fitness.setText(avg_fitness)
+ self.m_session_mdl.md_runstats["AVERAGES"]["AVG_FITNESS"] = avg_fitness
+
# i got rid of dominant stats, jmc
# dom_fitness = str(stats.GetDomFitness())
# string_length = len(dom_fitness)
@@ -105,6 +111,7 @@
num_orgs = stats.GetNumCreatures()
self.m_num_orgs.setText(QString("%1").arg(num_orgs))
+ self.m_session_mdl.md_runstats["TOTAL_ORGS"] = num_orgs
avg_gest = "%d" %(stats.GetAveGestation())
# string_length = len(avg_gest)
@@ -112,12 +119,16 @@
# avg_gest = avg_gest + '0'
# string_length = string_length+1
self.m_avg_gest.setText(QString("%1").arg(avg_gest))
+ self.m_session_mdl.md_runstats["AVERAGES"]["AVG_GESTATION"] = avg_gest
+
avg_merit = "%d" %(stats.GetAveMerit())
self.m_avg_merit.setText(QString("%1").arg(avg_merit))
+ self.m_session_mdl.md_runstats["AVERAGES"]["AVG_MERIT"] = avg_merit
avg_age = "%d" %(stats.GetAveCreatureAge())
self.m_avg_age.setText(QString("%1").arg(avg_age))
+ self.m_session_mdl.md_runstats["AVERAGES"]["AVG_AGE"] = avg_age
avg_genome_length = "%d" %(stats.GetAveSize())
# self.m_avg_genome_length.setText(QString("%1").arg(avg_genome_length))
@@ -125,16 +136,25 @@
#TASK OUTLOOK
# @WRE: get current update of run
- age_now ="%d" %(stats.GetUpdate())
+ age_now ="%d" % (stats.GetUpdate())
+ self.m_session_mdl.md_runstats["UPDATE"] = age_now
+ self.m_session_mdl.md_runstats["TASKS"] = []
+ self.m_session_mdl.md_runstats["TASKSRAW"] = []
+
num_not = str(stats.GetTaskLastCount(0))
# @WRE: adding first completion
if ((int(self.m_stat_task_first_complete[0]) <= 0) and (0 < int(num_not))):
self.m_stat_task_first_complete[0] = age_now
if ((int(self.m_stat_task_first_complete[0]) > 0) or (0 < int(num_not))):
self.m_num_not.setText("%s (1st@ %d)" %(num_not, int(self.m_stat_task_first_complete[0])))
+ mdrsstr = "Not: %s (1st@ %d)" % (num_not, int(self.m_stat_task_first_complete[0]))
else:
self.m_num_not.setText(num_not)
+ mdrsstr = "Not: %s" % (num_not)
+
+ self.m_session_mdl.md_runstats["TASKS"].append(mdrsstr)
+ self.m_session_mdl.md_runstats["TASKSRAW"].append(num_not)
num_nand = str(stats.GetTaskLastCount(1))
# @WRE: adding first completion
@@ -142,75 +162,124 @@
self.m_stat_task_first_complete[1] = age_now
if ((int(self.m_stat_task_first_complete[1]) > 0) or (0 < int(num_nand))):
self.m_num_nand.setText("%s (1st@ %d)" %(num_nand, int(self.m_stat_task_first_complete[1])))
+ mdrsstr = "Nand: %s (1st@ %d)" % (num_nand, int(self.m_stat_task_first_complete[1]))
else:
self.m_num_nand.setText(num_nand)
+ mdrsstr = "Nand: %s" % (num_nand)
+ self.m_session_mdl.md_runstats["TASKS"].append(mdrsstr)
+ self.m_session_mdl.md_runstats["TASKSRAW"].append(num_nand)
+
num_and = str(stats.GetTaskLastCount(2))
# @WRE: adding first completion
if ((int(self.m_stat_task_first_complete[2]) <= 0) and (0 < int(num_and))):
self.m_stat_task_first_complete[2] = age_now
if ((int(self.m_stat_task_first_complete[2]) > 0) or (0 < int(num_and))):
self.m_num_and.setText("%s (1st@ %d)" %(num_and, int(self.m_stat_task_first_complete[2])))
+ mdrsstr = "And: %s (1st@ %d)" % (num_and, int(self.m_stat_task_first_complete[2]))
else:
self.m_num_and.setText(num_and)
+ mdrsstr = "And: %s" % (num_and)
+ self.m_session_mdl.md_runstats["TASKS"].append(mdrsstr)
+ self.m_session_mdl.md_runstats["TASKSRAW"].append(num_and)
+
num_ornot = str(stats.GetTaskLastCount(3))
# @WRE: adding first completion
if ((int(self.m_stat_task_first_complete[3]) <= 0) and (0 < int(num_ornot))):
self.m_stat_task_first_complete[3] = age_now
if ((int(self.m_stat_task_first_complete[3]) > 0) or (0 < int(num_ornot))):
self.m_num_ornot.setText("%s (1st@ %d)" %(num_ornot, int(self.m_stat_task_first_complete[3])))
+ mdrsstr = "Orn: %s (1st@ %d)" % (num_ornot, int(self.m_stat_task_first_complete[3]))
else:
self.m_num_ornot.setText(num_ornot)
+ mdrsstr = "Orn: %s" % (num_ornot)
+ self.m_session_mdl.md_runstats["TASKS"].append(mdrsstr)
+ self.m_session_mdl.md_runstats["TASKSRAW"].append(num_ornot)
+
num_or = str(stats.GetTaskLastCount(4))
# @WRE: adding first completion
if ((int(self.m_stat_task_first_complete[4]) <= 0) and (0 < int(num_or))):
self.m_stat_task_first_complete[4] = age_now
if ((int(self.m_stat_task_first_complete[4]) > 0) or (0 < int(num_or))):
self.m_num_or.setText("%s (1st@ %d)" %(num_or, int(self.m_stat_task_first_complete[4])))
+ mdrsstr = "Or: %s (1st@ %d)" % (num_or, int(self.m_stat_task_first_complete[4]))
else:
self.m_num_or.setText(num_or)
+ mdrsstr = "Or: %s" % (num_or)
+ self.m_session_mdl.md_runstats["TASKS"].append(mdrsstr)
+ self.m_session_mdl.md_runstats["TASKSRAW"].append(num_or)
+
num_andnot = str(stats.GetTaskLastCount(5))
# @WRE: adding first completion
if ((int(self.m_stat_task_first_complete[5]) <= 0) and (0 < int(num_andnot))):
self.m_stat_task_first_complete[5] = age_now
if ((int(self.m_stat_task_first_complete[5]) > 0) or (0 < int(num_andnot))):
self.m_num_andnot.setText("%s (1st@ %d)" %(num_andnot, int(self.m_stat_task_first_complete[5])))
+ mdrsstr = "Andn: %s (1st@ %d)" % (num_andnot, int(self.m_stat_task_first_complete[5]))
else:
self.m_num_andnot.setText(num_andnot)
+ mdrsstr = "Andn: %s" % (num_andnot)
+ self.m_session_mdl.md_runstats["TASKS"].append(mdrsstr)
+ self.m_session_mdl.md_runstats["TASKSRAW"].append(num_andnot)
+
num_nor = str(stats.GetTaskLastCount(6))
# @WRE: adding first completion
if ((int(self.m_stat_task_first_complete[6]) <= 0) and (0 < int(num_nor))):
self.m_stat_task_first_complete[6] = age_now
if ((int(self.m_stat_task_first_complete[6]) > 0) or (0 < int(num_nor))):
self.m_num_nor.setText("%s (1st@ %d)" %(num_nor, int(self.m_stat_task_first_complete[6])))
+ mdrsstr = "Nor: %s (1st@ %d)" % (num_nor, int(self.m_stat_task_first_complete[6]))
else:
self.m_num_nor.setText(num_nor)
+ mdrsstr = "Nor: %s" % (num_nor)
+ self.m_session_mdl.md_runstats["TASKS"].append(mdrsstr)
+ self.m_session_mdl.md_runstats["TASKSRAW"].append(num_nor)
+
num_xor = str(stats.GetTaskLastCount(7))
# @WRE: adding first completion
if ((int(self.m_stat_task_first_complete[7]) <= 0) and (0 < int(num_xor))):
self.m_stat_task_first_complete[7] = age_now
if ((int(self.m_stat_task_first_complete[7]) > 0) or (0 < int(num_xor))):
self.m_num_xor.setText("%s (1st @ %d)" %(num_xor, int(self.m_stat_task_first_complete[7])))
+ mdrsstr = "Xor: %s (1st@ %d)" % (num_xor, int(self.m_stat_task_first_complete[7]))
else:
self.m_num_xor.setText(num_xor)
+ mdrsstr = "Xor: %s" % (num_xor)
+ self.m_session_mdl.md_runstats["TASKS"].append(mdrsstr)
+ self.m_session_mdl.md_runstats["TASKSRAW"].append(num_xor)
+
num_equals = str(stats.GetTaskLastCount(8))
# @WRE: adding first completion
if ((int(self.m_stat_task_first_complete[8]) <= 0) and (0 < int(num_equals))):
self.m_stat_task_first_complete[8] = age_now
if ((int(self.m_stat_task_first_complete[8]) > 0) or (0 < int(num_equals))):
self.m_num_equals.setText("%s (1st@ %d)" %(num_equals, int(self.m_stat_task_first_complete[8])))
+ mdrsstr = "Equ: %s (1st@ %d)" % (num_equals, int(self.m_stat_task_first_complete[8]))
else:
self.m_num_equals.setText(num_equals)
+ mdrsstr = "Equ: %s" % (num_equals)
+
+ self.m_session_mdl.md_runstats["TASKS"].append(mdrsstr)
+ self.m_session_mdl.md_runstats["TASKSRAW"].append(num_equals)
if self.m_clicked_cell_number>= 0:
self.updateOrgReportSlot(self.m_clicked_cell_item)
+ # @WRE: Whole population statistics for diversity and multi-dish
+ self.doWholePopStats()
+
+ # Launch updates for Multi-Dish display
+ self.m_session_mdl.m_session_mdtr.emit(
+ PYSIGNAL("haveMDDiversityUpdate"), ())
+ self.m_session_mdl.m_session_mdtr.emit(
+ PYSIGNAL("haveMDRunStatsUpdate"), ())
+
def notButtonClickedSlot(self):
self.m_stat_task_button_states[0] = self.m_not_button.state()
self.m_session_mdl.m_session_mdtr.emit(
@@ -350,6 +419,8 @@
phenotype = organism.GetPhenotype()
genotype = organism.GetGenotype()
+ # print "organism at %s : gen.= %s , phen.= %s" % (self.m_clicked_cell_number,genotype,phenotype)
+
# print info about the org clicked on
self.m_session_mdl.m_current_cell_genome = str(organism.GetGenome().AsString())
@@ -560,3 +631,215 @@
self.m_num_xor.setText("-")
self.m_num_equals.setText("-")
self.m_stat_task_first_complete = [0,0,0,0,0,0,0,0,0]
+
+ def getPhenotypeStr(self,grid_cell):
+ """
+ getPhenotypeStr
+
+ Method to return a string representing the phenotype.
+ Represention: 1 if the task was done, 0 if not. Nine places
+ for the logic-9 environment.
+ """
+
+ clicked_cell = self.m_avida.m_population.GetCell(int(grid_cell))
+
+ organism = clicked_cell.GetOrganism()
+ phenotype = organism.GetPhenotype()
+ # genotype = organism.GetGenotype()
+
+ phenstr = ""
+
+ # get the Tarray of tasks
+ m_clickedOrg_task_count = phenotype.GetLastTaskCount()
+
+ num_not_clickedOrg = m_clickedOrg_task_count[0]
+ if num_not_clickedOrg>0:
+ phenstr = "1"
+ else:
+ phenstr = "0"
+
+ num_nand_clickedOrg = m_clickedOrg_task_count[1]
+ if num_nand_clickedOrg>0:
+ phenstr = phenstr + "1"
+ else:
+ phenstr = phenstr + "0"
+
+ num_and_clickedOrg = m_clickedOrg_task_count[2]
+ if num_and_clickedOrg>0:
+ phenstr = phenstr + "1"
+ else:
+ phenstr = phenstr + "0"
+
+ num_ornot_clickedOrg = m_clickedOrg_task_count[3]
+ if num_ornot_clickedOrg>0:
+ phenstr = phenstr + "1"
+ else:
+ phenstr = phenstr + "0"
+
+ num_or_clickedOrg = m_clickedOrg_task_count[4]
+ if num_or_clickedOrg>0:
+ phenstr = phenstr + "1"
+ else:
+ phenstr = phenstr + "0"
+
+ num_andnot_clickedOrg = m_clickedOrg_task_count[5]
+ if num_andnot_clickedOrg>0:
+ phenstr = phenstr + "1"
+ else:
+ phenstr = phenstr + "0"
+
+ num_nor_clickedOrg = m_clickedOrg_task_count[6]
+ if num_nor_clickedOrg>0:
+ phenstr = phenstr + "1"
+ else:
+ phenstr = phenstr + "0"
+
+ num_xor_clickedOrg = m_clickedOrg_task_count[7]
+ if num_xor_clickedOrg>0:
+ phenstr = phenstr + "1"
+ else:
+ phenstr = phenstr + "0"
+
+ num_equals_clickedOrg = m_clickedOrg_task_count[8]
+ if num_equals_clickedOrg>0:
+ phenstr = phenstr + "1"
+ else:
+ phenstr = phenstr + "0"
+
+ return phenstr
+
+ def doWholePopStats(self):
+ """
+ doWholePopStats
+
+ These stats are especially needed to fulfill requirements for the
+ Multi-Dish version of Avida-ED.
+
+ Theory of operation: once per update, go over the entire population,
+ getting useful statistics, including diversity measures. Display the
+ diversity measures on screen. If possible, save them to a database.
+ """
+
+ # pop : a list of occupied cells
+ # popsize : how many occupied cells we have
+ # popgen : dictionary: cell => genome
+ # popphen : dictionary: cell => phenotypes
+
+ # Getting ancestor string:
+ # self.m_session_mdl.m_cell_num_ancestor_name_dict[str(self.m_clicked_cell_number)])
+ # Pattern: name-pos-cell
+ # Can't count on "name" not including "-" characters, so use negative indexing
+
+ # Get gridmaster object to translate cell locations if multi-dish
+ if (True == self.m_session_mdl.m_is_multi_dish):
+ grid = Grids(self.m_session_mdl.m_multi_dish_dict["MD_SD_X"],
+ self.m_session_mdl.m_multi_dish_dict["MD_SD_Y"],
+ self.m_session_mdl.m_multi_dish_dict["MD_SD_SIZEX"],
+ self.m_session_mdl.m_multi_dish_dict["MD_SD_SIZEY"])
+ md_sds = int(self.m_session_mdl.m_multi_dish_dict["MD_SD_X"]) * int(self.m_session_mdl.m_multi_dish_dict["MD_SD_Y"])
+
+ # Collect diversity data
+ # Clear the dictionary
+ self.m_session_mdl.md_diversity = {}
+
+ # Establish dictionaries
+ self.m_session_mdl.md_diversity["POP_GEN"] = {}
+ self.m_session_mdl.md_diversity["POP_PHEN"] = {}
+
+ self.m_session_mdl.md_diversity["NATIVES"] = {}
+ self.m_session_mdl.md_diversity["IMMIGRANTS"] = {}
+ self.m_session_mdl.md_diversity["EMIGRANTS"] = {}
+
+ self.m_session_mdl.md_diversity["POP_COUNTS"] = {}
+
+ # Establish lists and counters
+ self.m_session_mdl.md_diversity["POP_GEN"]["TOTAL"] = []
+ self.m_session_mdl.md_diversity["POP_COUNTS"]["TOTAL"] = 0
+ if (True == self.m_session_mdl.m_is_multi_dish): # if multi-dish
+ for ii in range(md_sds): # number of subdishes
+ self.m_session_mdl.md_diversity["POP_GEN"][str(ii)] = []
+ self.m_session_mdl.md_diversity["POP_COUNTS"][str(ii)] = 0
+
+ self.m_session_mdl.md_diversity["POP_PHEN"]["TOTAL"] = []
+ if (True == self.m_session_mdl.m_is_multi_dish): # if multi-dish
+ for ii in range(md_sds): # number of subdishes
+ self.m_session_mdl.md_diversity["POP_PHEN"][str(ii)] = []
+
+ if (True == self.m_session_mdl.m_is_multi_dish): # if multi-dish
+ for ii in range(md_sds): # number of subdishes
+ self.m_session_mdl.md_diversity["NATIVES"][str(ii)] = 0
+ self.m_session_mdl.md_diversity["IMMIGRANTS"][str(ii)] = 0
+ self.m_session_mdl.md_diversity["EMIGRANTS"][str(ii)] = 0
+
+ #self.session_model.md_diversity["POP_GEN"] = {}
+ #self.m_avida.m_population.GetCell(int(self.m_clicked_cell_number)).IsOccupied()
+
+ # For all the cells in the population
+ # Borrowed control flow from pyPetriDishCtrl.py
+ if self.m_avida is not None:
+ self.m_change_list = self.m_avida.m_avida_threaded_driver.GetChangeList()
+ self.m_world_w = cConfig.GetWorldX()
+ self.m_world_h = cConfig.GetWorldY()
+ else:
+ self.m_world_w = 30
+ self.m_world_h = 30
+ # print "Avida-ED world w = %s, h = %s" % (self.m_world_w,self.m_world_h)
+ if self.m_avida != None:
+ for x in range(self.m_world_w):
+ for y in range(self.m_world_h):
+ cell_ndx = x + self.m_world_w*y
+
+ cell = self.m_avida.m_population.GetCell(cell_ndx)
+ # Check: is it occupied?
+ if cell.IsOccupied() == True:
+ self.m_session_mdl.md_diversity["POP_COUNTS"]["TOTAL"] += 1
+
+ organism = cell.GetOrganism()
+ genome = organism.GetGenome()
+ phenotype = organism.GetPhenotype()
+ # population_dict[cell.GetID()] = str(genome.AsString())
+ # ancestor_dict[cell.GetID()] = str(organism.GetLineageLabel())
+
+ # Get the genome string
+ thisgenstr = str(genome.AsString())
+ self.m_session_mdl.md_diversity["POP_GEN"]["TOTAL"].append(thisgenstr)
+
+ # Get the phenotype string
+ thisphenstr = self.getPhenotypeStr(cell.GetID())
+ # print "Phenotype string %s" % (thisphenstr)
+ self.m_session_mdl.md_diversity["POP_PHEN"]["TOTAL"].append(thisphenstr)
+
+ # If MD
+ if (True == self.m_session_mdl.m_is_multi_dish): # if multi-dish
+
+ # Figure out the ancestral subdish position
+ ll = str(organism.GetLineageLabel())
+ # anc = self.m_session_mdl.m_ancestors_dict[cell.GetID()]
+ anc = self.m_session_mdl.m_ancestors_dict[str(ll)]
+ anclist = anc.split("-")
+ anc_pos = anclist[-2]
+ #print "Org at %s has ancestor %s, anc. SD pos. %s" % (cell_ndx,anc,anc_pos)
+
+ # Figure out the current subdish position
+ sdinfo = grid.serverCell2ClientCell(int(self.m_session_mdl.m_multi_dish_dict["MD_SD_X"]),
+ int(self.m_session_mdl.m_multi_dish_dict["MD_SD_Y"]),
+ int(self.m_session_mdl.m_multi_dish_dict["MD_SD_SIZEX"]),
+ int(self.m_session_mdl.m_multi_dish_dict["MD_SD_SIZEY"]),
+ int(cell_ndx))
+ #print "sdinfo: %s" % (sdinfo)
+ cur_pos = sdinfo[-1]
+ #print "Anc. pos = %s, Cur. pos = %s" % (anc_pos, cur_pos)
+ # Increment count in native or immigrant tally for subdish
+ if (int(anc_pos) == int(cur_pos)):
+ #print "add to native count"
+ self.m_session_mdl.md_diversity["NATIVES"][str(cur_pos)] += 1
+ else:
+ self.m_session_mdl.md_diversity["IMMIGRANTS"][str(cur_pos)] += 1
+ self.m_session_mdl.md_diversity["EMIGRANTS"][str(anc_pos)] += 1
+
+ # SubDish diversity data
+ self.m_session_mdl.md_diversity["POP_GEN"][str(cur_pos)].append(thisgenstr)
+ self.m_session_mdl.md_diversity["POP_PHEN"][str(cur_pos)].append(thisphenstr)
+
+ pass
+
Added: branches/developers/avida-edward/source/python/AvidaGui2/pyPRNGState.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyPRNGState.py (rev 0)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyPRNGState.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -0,0 +1,211 @@
+"""
+pyPRNGState.py
+
+Provides a global stack for interrupting the use of the global C++ pseudo-random number generator and
+using it for a set of computations.
+
+Provides a registry for status and pause functions for processes that use the global C++ PRNG.
+
+"""
+
+#import ctools
+#from AvidaCore import cAnalyzeGenotype, cGenome, cInstruction, cInstUtil, cRandom, cString, cTools
+from AvidaCore import cRandom, cTools
+
+import qt
+
+class StackType():
+ """
+ StackType
+ Abstract stack data type.
+ Mostly a direct use of Python list methods, but offers the "top"
+ operation in addition and a push() alias for append().
+ """
+ def __init__(self):
+ # A list is the basic data structure
+ # An empty list is the start
+ self.stk = []
+
+ def push(self,item):
+ # Add an item to the top of the stack
+ self.stk.append(item)
+
+ def pop(self):
+ # Remove an item from the top of the stack
+ return(self.stk.pop())
+
+ def top(self):
+ return(self.stk[-1])
+
+# Make the class one that can generate and receive signals by basing it on
+# a Qt object. Not used so far, but doesn't hurt to have it.
+class PRNGState(QObject):
+ """
+ PRNGState
+
+ Theory of operation:
+
+ A PRNGState object should be instantiated on the start of Avida-ED.
+
+ All processes requiring the use of the global pseudo-random number
+ generator (PRNG) should provide six items:
+ - name of the process
+ - a method that provides the status of the process
+ - a method that pauses the process
+ - a method that will resume the process
+ - whether the random seed to be used is based on time()
+ - a random seed value (will be 1 for the Organism view)
+
+ The global PRNG-using process should be added to the PRNGState with
+ the add() method before it first begins. The add() method will set up
+ the global PRNG state and preserve the state needed by any previous
+ user. The process may then be started safely.
+
+ On end of the current process, the PRNGState remove() method should
+ be called, which will restore the previous user process by setting
+ the PRNG state last used and then running the resume() function of the
+ prior process.
+
+ """
+ def setPRNG(self,prng_state):
+ """
+ setPRNG
+ Method to restore a global PRNG state preparatory to resuming a
+ PRNG-using process.
+ """
+ # Restore random number generator state.
+ cTools.globalRandom().Clone(prng_state)
+
+ def resetPRNG(self,seed_based_on_time,seed):
+ """
+ resetPRNG
+ Method to start the PRNG with a new seed.
+ """
+ # Reset random number generator state.
+ if self.m_seed_based_on_time:
+ cTools.globalRandom().ResetSeed(-1)
+ else:
+ cTools.globalRandom().ResetSeed(seed)
+
+ def __init__(self):
+ """
+ __init__
+ Create the various dictionaries and data structures to handle the global PRNG.
+ """
+ # Create empty status dict
+ self.status = {}
+ # Create empty pause dict
+ self.pause = {}
+ # Create empty resume dict
+ self.resume = {}
+
+ # Create an empty global PRNG users and state stacks
+ self.users = StackType()
+ self.states = StackType()
+
+ def add(self,processname,statusfunc,pausefunc,resumefunc,seed_based_on_time,seed):
+ """
+ add
+ Method to add a process to the users stack, pausing any previous global PRNG-using
+ process.
+ """
+ # A process needs the global PRNG
+ # Pause the currently running global PRNG user, if there is one
+ olduser = self.users.top()
+ if (None <> olduser): # If there is no current user, nothing special need be done
+ # Need to pause the old user of the global PRNG
+ self.pause[olduser]()
+ # Push the global PRNG state for the just-paused process
+ # Save random number generator state.
+ random_number_generator_state = cRandom(cTools.globalRandom())
+ self.states.push(random_number_generator_state)
+ # Now set the new process up for global PRNG use
+ self.users.push(processname)
+ self.status[processname] = statusfunc
+ self.pause[processname] = pausefunc
+ self.resume[processname] = resumefunc
+ self.resetPRNG(seed_based_on_time,seed)
+
+ def remove(self):
+ """
+ remove
+ Method to remove the top value from the users stack and
+ restore the prior PRNG state.
+ """
+ ruser = self.users.pop()
+ prng_state = self.states.pop()
+ if (None == prng_state): # This is a problem; should never happen
+ print "PRNG remove ERROR: None state encountered. **** VERY BAD THING ****"
+ else:
+ # There is a prior state, so set it up
+ setPRNG(prng_state)
+ # Now to resume the process of the prior user
+ olduser = self.states.top()
+ if (None <> olduser):
+ self.resume[olduser]()
+
+
+
+
+class AbstractProc(QObject):
+ def __init__(self,name):
+ self.name = name
+ self.run_state = "Not started"
+
+ def status(self):
+ return(self.run_state)
+
+ def pause(self):
+ self.run_state = "Paused"
+
+ def resume(self):
+ self.run_state = "Running"
+
+ def stop(self):
+ self.run_state = "Stopped"
+
+ def do_process(self):
+ if ("Running" == self.run_State):
+ self.process_step()
+
+ def process_step(self):
+ pass
+
+
+class ProcA(AbstractProc):
+ def __init__(self,name):
+ AbstractProc.__init__(name)
+
+ def status(self):
+ return(self.run_state)
+
+ def pause(self):
+ self.run_state = "Paused"
+
+ def resume(self):
+ self.run_state = "Running"
+
+ def stop(self):
+ self.run_state = "Stopped"
+
+ def do_process(self):
+ if ("Running" == self.run_State):
+ self.process_step()
+
+ def process_step(self):
+ pass
+
+
+
+if (1): # Testing
+
+ print "Testing PRNGState...\n"
+ myprngctrl = PRNGState()
+
+
+ proca = ProcA("ProcA")
+
+
+ print "ProcA name = %s, state = %s\n" % (proca.name,proca.status())
+
+ print "Testing PRNGState... Done.\n";
Modified: branches/developers/avida-edward/source/python/AvidaGui2/pyPetriConfigureCtrl.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyPetriConfigureCtrl.py 2009-08-04 03:26:21 UTC (rev 3356)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyPetriConfigureCtrl.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -234,6 +234,10 @@
def FillDishSlot(self, dish_name, petri_dict):
self.full_petri_dict = petri_dict.dictionary
+
+ print "Dictionary sections:"
+ print self.full_petri_dict.keys()
+
settings_dict = petri_dict.dictionary["SETTINGS"]
# Erase all items for the ancestor list
@@ -451,12 +455,19 @@
def CreateFilesFromPetriSlot(self, out_dir = None):
+ # print "********************** CreateFilesFromPetriSlot *************************************************"
# The input files will be placed in a python generated temporary directory
# ouput files will be stored in tmp_dir/output until the data is frozen
# (ie saved)
-
- self.full_petri_dict["SETTINGS"] = self.Form2Dictionary()
+
+ # @WRE: Problem here with non-square layouts
+ # Figure out if we've read a full petri dish. If so, we already have all the "SETTINGS" we need.
+ if (self.full_petri_dict.has_key("CELLS")):
+ #print "Not calling Form2Dictionary"
+ pass
+ else:
+ self.full_petri_dict["SETTINGS"] = self.Form2Dictionary()
write_object = pyWriteAvidaCfgEvent(self.full_petri_dict,
self.m_session_mdl,
self.m_session_mdl.m_current_workspace,
@@ -465,8 +476,10 @@
self.m_session_mdl.m_session_mdtr.emit(
PYSIGNAL("doInitializeAvidaPhaseIISig"),
(os.path.join(self.m_session_mdl.m_tempdir, "avida_cfg.avida"),))
+ print "Using temporary directory %s" % (self.m_session_mdl.m_tempdir)
def Form2Dictionary(self):
+ # print "Form2Dictionary"
settings_dict = {}
# Write START_CREATUREi for all the organisms in the Ancestor Icon View
@@ -539,12 +552,22 @@
return settings_dict
def FreezePetriSlot(self, population_dict = None, ancestor_dict = None, send_reset_signal = False, send_quit_signal = False):
+ print "pyPetriConfigureCtrl.FreezePetriSlot()"
if len(population_dict) == 0:
freeze_empty_only_flag = True;
else:
freeze_empty_only_flag = False;
tmp_dict = {}
- tmp_dict["SETTINGS"] = self.Form2Dictionary()
+
+ # @WRE: Handle multi-dish case
+ if (True == self.m_session_mdl.m_is_multi_dish):
+ print "Multi-Dish case"
+ tmp_dict["MULTI_DISH"] = self.m_session_mdl.m_multi_dish_dict
+ # ??? Need to carry over settings from previous, not collect them from the form
+ tmp_dict["SETTINGS"] = self.Form2Dictionary()
+ else:
+ print "Regular dish case"
+ tmp_dict["SETTINGS"] = self.Form2Dictionary()
m_pop_up_freezer_file_name = pyFreezeDialogCtrl()
file_name = m_pop_up_freezer_file_name.showDialog(self.m_session_mdl, freeze_empty_only_flag)
file_name_len = len(file_name.rstrip())
@@ -578,7 +601,6 @@
self.m_session_mdl.saved_empty_dish = True
else:
self.m_session_mdl.saved_full_dish = True
-
# Have program redraw the freezer menu pane
@@ -689,6 +711,8 @@
freezer_item_name_temp = freezer_item_name
self.m_session_mdl.new_empty_dish = True
thawed_item = pyReadFreezer(freezer_item_name_temp)
+ print "WRE: new status bar message signal."
+ self.m_session_mdl.m_session_mdtr.emit(PYSIGNAL("statusBarMessageSig"), ("Large dishes may take a few minutes to process. Be patient.",))
self.m_session_mdl.m_session_mdtr.emit(PYSIGNAL("doDefrostDishSig"),
(os.path.splitext((os.path.split(str(freezer_item_name))[1]))[0], thawed_item,))
Modified: branches/developers/avida-edward/source/python/AvidaGui2/pyPetriConfigureView.ui
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyPetriConfigureView.ui 2009-08-04 03:26:21 UTC (rev 3356)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyPetriConfigureView.ui 2009-08-05 16:45:50 UTC (rev 3357)
@@ -238,7 +238,7 @@
<number>1</number>
</property>
<property name="maxValue">
- <number>100</number>
+ <number>300</number>
</property>
<property name="lineStep">
<number>1</number>
@@ -253,7 +253,7 @@
<enum>Horizontal</enum>
</property>
<property name="toolTip" stdset="0">
- <string><p>Set the height and width of the petri dish (1 to 100)</p></string>
+ <string><p>Set the height and width of the petri dish (1 to 300)</p></string>
</property>
</widget>
<widget class="QLayoutWidget" row="1" column="1">
Modified: branches/developers/avida-edward/source/python/AvidaGui2/pyPetriDishCtrl.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyPetriDishCtrl.py 2009-08-04 03:26:21 UTC (rev 3356)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyPetriDishCtrl.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -27,6 +27,7 @@
self.clearWState(Qt.WState_Polished)
def construct(self, session_mdl):
+ print "pyPetriDishCtrl.construct()"
self.m_session_mdl = session_mdl
self.m_avida = None
@@ -102,11 +103,13 @@
self.vbarScrollPrevLineSlot)
def doStartAvidaSlot (self):
+ print "pyPetriDishCtrl.doStartAvidaSlot"
# self.m_avida_has_started = True //replacing with the session_mdl version
self.m_session_mdl.m_avida_has_started = True
def restart(self):
+ print "pyPetriDishCtrl.restart"
self.m_cell_info = None
self.m_changed_cell_items = []
self.m_color_lookup_functor = None
@@ -144,6 +147,7 @@
self.m_canvas)
def setAvidaSlot(self, avida):
+ print "pyPetriDishCtrl.setAvidaSlot()"
descr(avida)
old_avida = self.m_avida
self.m_avida = avida
@@ -205,6 +209,7 @@
self.updateCellItems(True)
def setDragSlot(self, org_clicked_on_item = None):
+ print "pyPetriDishCtrl.setDragSlot()"
descr(org_clicked_on_item)
if org_clicked_on_item:
clicked_cell_num = org_clicked_on_item.m_population_cell.GetID()
@@ -313,7 +318,7 @@
if self.m_canvas: self.m_canvas.update()
def extractPopulationSlot(self, send_reset_signal = False, send_quit_signal = False):
-
+ print "pyPetriDishCtrl.extractPopulationSlot()"
# If there is an active Avida object find all the cells that are occupied
# and place them in a dictionary. Fire off the signal for the next freezer
# phase with that signal.
Modified: branches/developers/avida-edward/source/python/AvidaGui2/pyReadFreezer.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyReadFreezer.py 2009-08-04 03:26:21 UTC (rev 3356)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyReadFreezer.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -5,6 +5,7 @@
class pyReadFreezer:
def __init__(self, in_file_name = None):
+ print "pyReadFreezer.__init__()"
self.file_name = in_file_name
self.dictionary = {}
freezefile = open(self.file_name)
@@ -27,12 +28,18 @@
if line[0] == "*":
section_key = line[1:].upper()
self.dictionary[section_key] = {}
+ print "Added dictionary section '%s'" % (section_key)
+
+
else:
# split into key and value (which could be multiple words)
var_name, value = line.split(' ',1)
self.dictionary[section_key][var_name.upper()] = value
+
+ # ??? debug, turn off
+ # print self.dictionary["SETTINGS"]
def GetDictionary(self):
return self.dictionary
Modified: branches/developers/avida-edward/source/python/AvidaGui2/pyWriteAvidaCfgEvent.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyWriteAvidaCfgEvent.py 2009-08-04 03:26:21 UTC (rev 3356)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyWriteAvidaCfgEvent.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -6,6 +6,8 @@
from descr import *
+from pyMDMkEnv import *
+
# Class to write the working avida_cfg, event and environment files based on
# the contents of settings dictionary
@@ -23,21 +25,36 @@
settings_dict = {}
else:
settings_dict = in_dict["SETTINGS"]
+ self.m_settings_dict = settings_dict
+ print "pyWriteAvidaCfgEvent.__init__()"
+ print settings_dict
# Copies default event file and add to the
# temporary dictionary where the input files will live
shutil.copyfile(os.path.join(workspace_dir, "events.default"), os.path.join(tmp_in_dir, "events.cfg"))
+ # Assume that it is not a multi-dish, disprove that later
+ self.m_session_mdl.m_is_multi_dish = False
+
# If this is a full petri dish inject all the organisms, otherwise
# inject the start creature in the center of the grid
#if we have a full petri dish...
+ # Existence of "CELLS" section defines a full petri dish, except if this is the research version
if in_dict.has_key("CELLS") and \
(not (os.path.exists(os.path.join(workspace_dir,"research.version")))):
+
+ print " - full petri dish"
+
+ # Local reference to "CELLS"
cells_dict = in_dict["CELLS"]
+ # Local reference to "ORGANISMS"
organisms_dict = in_dict["ORGANISMS"]
+
+ print " - dish has %s organisms and %s cells" % (len(organisms_dict.keys()),len(cells_dict.keys()))
+
self.m_session_mdl.m_founding_cells_dict = cells_dict
if in_dict.has_key("ANCESTOR_NAMES"):
@@ -58,6 +75,14 @@
self.m_session_mdl.m_global_num_of_ancestors = \
len(session_mdl.m_cell_num_ancestor_name_dict)
+ # @WRE: Multi-dish?
+ if (in_dict.has_key("MULTI_DISH")):
+ self.m_session_mdl.m_multi_dish_dict = in_dict["MULTI_DISH"]
+ else:
+ self.m_session_mdl.m_multi_dish_dict = {}
+ if (0 < len(self.m_session_mdl.m_multi_dish_dict.keys())):
+ self.m_session_mdl.m_is_multi_dish = True
+
#if it is not a full petri dish
else:
self.m_session_mdl.m_cell_num_ancestor_name_dict = {}
@@ -71,6 +96,8 @@
world_x = settings_dict["WORLD-X"]
world_y = settings_dict["WORLD-Y"]
+ print "World size set as x = %s, y = %s" % (world_x, world_y)
+
# Count all ancestors with the name of the form START_CREATUREx
num_ancestors = 0
@@ -105,6 +132,12 @@
settings_dict["EVENT_FILE"] = os.path.join(tmp_in_dir, "events.cfg")
settings_dict["ENVIRONMENT_FILE"] = os.path.join(tmp_in_dir, "environment.cfg")
+
+ # @WRE: Handle Multi-Dish case separately
+ #if (True == self.m_session_mdl.m_is_multi_dish):
+ # self.writeMDEnvironmentFile(workspace_dir, settings_dict, self.m_session_mdl.m_multi_dish_dict)
+ #else: # Regular dish case
+
self.writeEnvironmentFile(workspace_dir, settings_dict)
settings_dict["INST_SET"] = os.path.join(tmp_in_dir, "inst_set.default")
avida_cfg_file_name = self.writeAvidaCfgFile(workspace_dir, tmp_in_dir, \
@@ -195,51 +228,73 @@
def writeEnvironmentFile(self, workspace_dir, settings_dict):
- orig_environment_file = open(os.path.join(workspace_dir, "environment.default"))
- lines = orig_environment_file.readlines()
- orig_environment_file.close()
- out_environment_file = open(settings_dict["ENVIRONMENT_FILE"], "w")
- for line in lines:
- comment_start = line.find("#")
- if comment_start > -1:
- if comment_start == 0:
- clean_line = ""
+ if (False == self.m_session_mdl.m_is_multi_dish): # This is not a multi-dish, so use the normal processing
+ orig_environment_file = open(os.path.join(workspace_dir, "environment.default"))
+ lines = orig_environment_file.readlines()
+ orig_environment_file.close()
+ out_environment_file = open(settings_dict["ENVIRONMENT_FILE"], "w")
+ for line in lines:
+ comment_start = line.find("#")
+ if comment_start > -1:
+ if comment_start == 0:
+ clean_line = ""
+ else:
+ clean_line = line[:comment_start]
else:
- clean_line = line[:comment_start]
- else:
- clean_line = line;
- clean_line = clean_line.strip()
- if len(clean_line) > 0:
- split_out = string.split(clean_line)
- command_name = split_out[0].upper()
+ clean_line = line;
+ clean_line = clean_line.strip()
+ if len(clean_line) > 0:
+ split_out = string.split(clean_line)
+ command_name = split_out[0].upper()
+
+ # if it is a reaction line check further (otherwise print the line)
+
+ if command_name == "REACTION":
+ resource_name = split_out[1].upper()
+ resource_key = "REWARD_" + resource_name
+ task_name = split_out[2]
+
+ # If the there is a reward key for this resource check further
+ # (otherwise print the line)
+
+ if settings_dict.has_key(resource_key) == True:
+
+ # If the value of the reward key is true print it out as is
+ # (otherwise print out as a zero bonus)
+
+ if settings_dict[resource_key] == "YES":
+ out_environment_file.write(line)
+ else:
+ out_environment_file.write("REACTION " + resource_name + " " +
+ task_name + " process:value=0.0:type=add\n")
+ else:
+ out_environment_file.write(line)
+ else:
+ out_environment_file.write(line)
+ out_environment_file.close()
+ else:
+ # This is where the multi-dish processing happens
+ # Need to write out both RESOURCE and REACTION definitions for spatial resources
+ # Need to make sure the order of initial resources corresponds to the canonical order
+ # for in-run tracking to work.
- # if it is a reaction line check further (otherwise print the line)
+ # ???
+ # Get a MkEnv object
+ # print self.m_settings_dict
+ print self.m_session_mdl.m_multi_dish_dict
- if command_name == "REACTION":
- resource_name = split_out[1].upper()
- resource_key = "REWARD_" + resource_name
- task_name = split_out[2]
+ mkenv = MkEnv(int(self.m_session_mdl.m_multi_dish_dict["MD_SD_X"]),
+ int(self.m_session_mdl.m_multi_dish_dict["MD_SD_Y"]),
+ int(self.m_session_mdl.m_multi_dish_dict["MD_SD_SIZEX"]),
+ int(self.m_session_mdl.m_multi_dish_dict["MD_SD_SIZEY"]))
- # If the there is a reward key for this resource check further
- # (otherwise print the line)
-
- if settings_dict.has_key(resource_key) == True:
+ # Have it write out the environment file
+ out_environment_file = str(settings_dict["ENVIRONMENT_FILE"])
+ mkenv.mkMDTemplate(out_environment_file,self.m_session_mdl.m_multi_dish_dict)
+
+
+ pass
- # If the value of the reward key is true print it out as is
- # (otherwise print out as a zero bonus)
-
- if settings_dict[resource_key] == "YES":
- out_environment_file.write(line)
- else:
- out_environment_file.write("REACTION " + resource_name + " " +
- task_name + " process:value=0.0:type=add\n")
- else:
- out_environment_file.write(line)
- else:
- out_environment_file.write(line)
-
- out_environment_file.close()
-
def modifyEventFile(self, cells_dict, organisms_dict, ancestor_link_dict, merits_dict,
event_file_name, tmp_out_dir = None):
Modified: branches/developers/avida-edward/source/python/AvidaGui2/pyWriteToFreezer.py
===================================================================
--- branches/developers/avida-edward/source/python/AvidaGui2/pyWriteToFreezer.py 2009-08-04 03:26:21 UTC (rev 3356)
+++ branches/developers/avida-edward/source/python/AvidaGui2/pyWriteToFreezer.py 2009-08-05 16:45:50 UTC (rev 3357)
@@ -20,7 +20,13 @@
elif out_file_name.endswith(".full"):
is_dish = True
- self.simplifyPopulation(in_dict)
+ if (in_dict.has_key("MULTI_DISH")):
+ # Multi-dish already has correct set of population links
+ self.simplifyPopulation(in_dict)
+ pass
+ else:
+ # Other dishes require fixup
+ self.simplifyPopulation(in_dict)
out_file_name = os.path.join(out_file_name, 'petri_dish')
elif out_file_name.endswith(".empty"):
@@ -40,6 +46,7 @@
elif is_dish == True:
for section in in_dict.keys():
+ print "writing out section '%s'" % (str(section))
# Always print out the petri dishes settings and if it is a full dish
# print out the cell and organism information
@@ -55,6 +62,7 @@
out_freezer_file.close()
def simplifyPopulation(self, in_dict = None):
+ print "simplifyPopulation"
if in_dict.has_key("POPULATION"):
pop_dict = in_dict["POPULATION"]
del in_dict["POPULATION"]
More information about the Avida-cvs
mailing list