1 /*
2  *  cAnalyzeGenotype.h
3  *  Avida
4  *
5  *  Called "analyze_genotype.hh" prior to 12/2/05.
6  *  Copyright 1999-2011 Michigan State University. All rights reserved.
7  *  Copyright 1993-2003 California Institute of Technology.
8  *
9  *
10  *  This file is part of Avida.
11  *
12  *  Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
13  *  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
14  *
15  *  Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public License along with Avida.
19  *  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #ifndef cAnalyzeGenotype_h
24 #define cAnalyzeGenotype_h
25 
26 #include "apto/core/RWLock.h"
27 #include "avida/core/Genome.h"
28 
29 #include <fstream>
30 
31 #ifndef cCPUMemory_h
32 #include "cCPUMemory.h"
33 #endif
34 #ifndef cGenotypeData_h
35 #include "cGenotypeData.h"
36 #endif
37 #ifndef cInstSet_h
38 #include "cInstSet.h"
39 #endif
40 #ifndef cLandscape_h
41 #include "cLandscape.h"
42 #endif
43 #ifndef cPhenPlastGenotype_h
44 #include "cPhenPlastGenotype.h"
45 #endif
46 #ifndef cString_h
47 #include "cString.h"
48 #endif
49 #ifndef cStringList_h
50 #include "cStringList.h"
51 #endif
52 #ifndef cStringUtil_h
53 #include "cStringUtil.h"
54 #endif
55 #ifndef tArray_h
56 #include "tArray.h"
57 #endif
58 #ifndef tArrayMap_h
59 #include "tArrayMap.h"
60 #endif
61 #ifndef tRCPtr_h
62 #include "tRCPtr.h"
63 #endif
64 #ifndef cPhenPlastSummary_h
65 #include "cPhenPlastSummary.h"
66 #endif
67 
68 // cAnalyzeGenotype    : Collection of information about loaded genotypes
69 
70 class cAvidaContext;
71 class cInstSet;
72 class cTestCPU;
73 class cWorld;
74 template<class T> class tDataCommandManager;
75 
76 class cAnalyzeGenotype;
77 
78 using namespace Avida;
79 
80 
81 class cAnalyzeGenotypeLink
82 {
83 private:
84   cAnalyzeGenotype *m_parent;
85   tList<cAnalyzeGenotype> m_child_list;
86 
87 public:
cAnalyzeGenotypeLink()88   cAnalyzeGenotypeLink() : m_parent(NULL) { m_child_list.Clear(); }
89 
SetParent(cAnalyzeGenotype * parent)90   void SetParent(cAnalyzeGenotype* parent) { m_parent = parent; }
GetParent()91   cAnalyzeGenotype* GetParent() { return m_parent; }
GetChildList()92   tList<cAnalyzeGenotype>& GetChildList() { return m_child_list; }
FindChild(cAnalyzeGenotype * child)93   cAnalyzeGenotype* FindChild(cAnalyzeGenotype* child) { return GetChildList().FindPtr(child); }
RemoveChild(cAnalyzeGenotype * child)94   cAnalyzeGenotype* RemoveChild(cAnalyzeGenotype* child) { return GetChildList().Remove(child); }
AddChild(cAnalyzeGenotype * child)95   void AddChild(cAnalyzeGenotype* child) { if(!FindChild(child)) GetChildList().PushRear(child); }
96 };
97 
98 
99 class cAnalyzeGenotype
100 {
101   friend class ReadToken;
102 private:
103   cWorld* m_world;
104   Genome m_genome;        // Full Genome
105   cString name;              // Name, if one was provided in loading
106   cCPUTestInfo m_cpu_test_info; // Use this test info
107 
108   struct sGenotypeDatastore : public cRCObject
109   {
110     Apto::RWLock rwlock;
111     mutable tArrayMap<int, cGenotypeData*> dmap;
112 
sGenotypeDatastoresGenotypeDatastore113     sGenotypeDatastore() { ; }
sGenotypeDatastoresGenotypeDatastore114     sGenotypeDatastore(const sGenotypeDatastore& ds) : cRCObject(ds) { ; } // Note that data objects are not copied right now
115 
116     ~sGenotypeDatastore();
117   };
118   tRCPtr<sGenotypeDatastore> m_data;
119 
120   cString aligned_sequence;  // Sequence (in ASCII) after alignment
121   cString tag;               // All genotypes in a batch can be tagged
122 
123   cAnalyzeGenotypeLink m_link;
124 
125   bool viable;
126 
127   // Group 1 : Load-in Stats (Only obtained if available for input file)
128   int id_num;
129   eBioUnitSource m_src;
130   cString m_src_args;
131   cString m_parent_str;
132   int parent_id;
133   int parent2_id;
134   int num_cpus;
135   int total_cpus;
136   int update_born;
137   int update_dead;
138   int depth;
139   cString m_cells;
140   cString m_gest_offsets;
141 
142   // Group 2 : Basic Execution Stats (Obtained from test CPUs)
143   int length;
144   int copy_length;
145   int exe_length;
146   double merit;
147   int gest_time;
148   double fitness;
149   int errors;
150   double div_type;
151   int mate_id;
152   cString executed_flags; // converted into a string
153   tArray<int> inst_executed_counts;
154   tArray<int> task_counts;
155   tArray<double> task_qualities;
156   tArray<int> internal_task_counts;
157   tArray<double> internal_task_qualities;
158   tArray<double> rbins_total;
159   tArray<double> rbins_avail;
160   tArray<int> collect_spec_counts;
161   tArray<int> m_env_inputs;
162   int m_mating_type; //@CHC
163   int m_mate_preference; //@CHC
164   int m_mating_display_a; //@CHC
165   int m_mating_display_b; //@CHC
166 
167 
168   // Group 3 : Stats requiring parental genotype (Also from test CPUs)
169   double fitness_ratio;
170   double efficiency_ratio;
171   double comp_merit_ratio;
172   int parent_dist;
173   int ancestor_dist;
174   int lineage_label;
175   cString parent_muts;
176 
177   // Group 4 : Landscape stats (obtained from testing all possible mutations)
178   class cAnalyzeKnockouts {
179   public:
180     // Calculations based off of all single knockouts
181     int dead_count;
182     int neg_count;
183     int neut_count;
184     int pos_count;
185 
186     // Extra calculations based off of double knockouts...
187     bool has_pair_info;  // Have these calculations been made?
188     int pair_dead_count;
189     int pair_neg_count;
190     int pair_neut_count;
191     int pair_pos_count;
192 
193     bool has_chart_info; // Keep a chart of which sites affect which tasks?
194     tArray< tArray<int> > task_counts;
195 
Reset()196     void Reset() {
197       dead_count = 0;
198       neg_count = 0;
199       neut_count = 0;
200       pos_count = 0;
201 
202       has_pair_info = false;
203       pair_dead_count = 0;
204       pair_neg_count = 0;
205       pair_neut_count = 0;
206       pair_pos_count = 0;
207 
208       has_chart_info = false;
209       task_counts.Resize(0);
210     }
211 
cAnalyzeKnockouts()212     cAnalyzeKnockouts() { Reset(); }
213   };
214   mutable cAnalyzeKnockouts* knockout_stats;
215 
216   mutable cLandscape* m_land;
217 
218   // Group 5 : More complex stats (obtained indvidually, through tests)
219   cString task_order;
220 
221 
222   // Group 6: Phenotypic Plasticity
223   mutable cPhenPlastSummary* m_phenplast_stats;
224 
NumCompare(double new_val,double old_val)225   int NumCompare(double new_val, double old_val) const {
226     if (new_val == old_val) return  0;
227     else if (new_val == 0)       return -2;
228     else if (old_val == 0)       return +2;
229     else if (new_val < old_val)  return -1;
230     // else if (new_val > old_val)
231     return +1;
232   }
233 
234   int CalcMaxGestation() const;
235   void CalcKnockouts(bool check_pairs = false, bool check_chart = false) const;
236   void CheckLand() const;
237   void CheckPhenPlast() const;
238   void SummarizePhenotypicPlasticity(const cPhenPlastGenotype& pp) const;
239 
240   static tDataCommandManager<cAnalyzeGenotype>* buildDataCommandManager();
241 
242 
243 
244 public:
245   cAnalyzeGenotype(cWorld* world, const Genome& genome);
246   cAnalyzeGenotype(const cAnalyzeGenotype& _gen);
247   ~cAnalyzeGenotype();
248 
249   static void Initialize();
250   static tDataCommandManager<cAnalyzeGenotype>& GetDataCommandManager();
251 
252   class ReadToken;
GetReadToken()253   ReadToken* GetReadToken() const { m_data->rwlock.ReadLock(); return new ReadToken(this); }
254 
255   void SetGenotypeData(int data_id, cGenotypeData* data);
GetGenotypeData(ReadToken * tk,int data_id)256   cGenotypeData* GetGenotypeData(ReadToken* tk, int data_id) const { tk->Validate(this); return m_data->dmap.GetWithDefault(data_id, NULL); }
257 
SetCPUTestInfo(cCPUTestInfo & in_cpu_test_info)258   void SetCPUTestInfo(cCPUTestInfo& in_cpu_test_info) { m_cpu_test_info = in_cpu_test_info; }
259 
260   void Recalculate(cAvidaContext& ctx, cCPUTestInfo* test_info = NULL, cAnalyzeGenotype* parent_genotype = NULL, int num_trials = 1);
261   void PrintTasks(std::ofstream& fp, int min_task = 0, int max_task = -1);
262   void PrintTasksQuality(std::ofstream& fp, int min_task = 0, int max_task = -1);
263   void PrintInternalTasks(std::ofstream& fp, int min_task = 0, int max_task = -1);
264   void PrintInternalTasksQuality(std::ofstream& fp, int min_task = 0, int max_task = -1);
265   void CalcLandscape(cAvidaContext& ctx);
266 
267   // Set...
268   void SetHWType(int hw_type);
269   void SetInstSet(const cString& inst_set);
270   void SetSequence(cString sequence);
SetName(const cString & _name)271   void SetName(const cString& _name) { name = _name; }
SetAlignedSequence(const cString & _seq)272   void SetAlignedSequence(const cString & _seq) { aligned_sequence = _seq; }
SetTag(const cString & _tag)273   void SetTag(const cString& _tag) { tag = _tag; }
274 
SetViable(bool _viable)275   void SetViable(bool _viable) { viable = _viable; }
276 
SetID(int _id)277   void SetID(int _id) { id_num = _id; }
SetSource(int _src)278   void SetSource(int _src) { m_src = (eBioUnitSource)_src; }
SetSourceArgs(const cString & src_args)279   void SetSourceArgs(const cString& src_args) { m_src_args = src_args; }
280   void SetParents(const cString& parent_str);
281   void SetParentID(int _parent_id);
282   void SetParent2ID(int _parent_id);
SetNumCPUs(int _cpus)283   void SetNumCPUs(int _cpus) { num_cpus = _cpus; }
SetTotalCPUs(int _cpus)284   void SetTotalCPUs(int _cpus) { total_cpus = _cpus; }
SetUpdateBorn(int _born)285   void SetUpdateBorn(int _born) { update_born = _born; }
SetUpdateDead(int _dead)286   void SetUpdateDead(int _dead) { update_dead = _dead; }
SetDepth(int _depth)287   void SetDepth(int _depth) { depth = _depth; }
SetCells(const cString & cells)288   void SetCells(const cString& cells) { m_cells = cells; }
SetGestOffsets(const cString & gest_offsets)289   void SetGestOffsets(const cString& gest_offsets) { m_gest_offsets = gest_offsets; }
290 
SetLength(int _length)291   void SetLength(int _length) { length = _length; }
SetCopyLength(int _length)292   void SetCopyLength(int _length) { copy_length = _length; }
SetExeLength(int _length)293   void SetExeLength(int _length) { exe_length = _length; }
SetMerit(double _merit)294   void SetMerit(double _merit) { merit = _merit; }
SetGestTime(int _gest)295   void SetGestTime(int _gest) { gest_time = _gest; }
SetFitness(double _fitness)296   void SetFitness(double _fitness) { fitness = _fitness; }
SetDivType(double _div_type)297   void SetDivType(double _div_type) { div_type = _div_type; }
SetMateID(int _mate_id)298   void SetMateID(int _mate_id) { mate_id = _mate_id; }
SetParentDist(int _dist)299   void SetParentDist(int _dist) { parent_dist = _dist; }
SetAncestorDist(int _dist)300   void SetAncestorDist(int _dist) { ancestor_dist = _dist; }
SetLineageLabel(int _label)301   void SetLineageLabel(int _label) { lineage_label = _label; }
302 
SetMatingType(int _mating_type)303   void SetMatingType(int _mating_type) { m_mating_type = _mating_type; } //@CHC
SetMatePreference(int _mate_preference)304   void SetMatePreference(int _mate_preference) { m_mate_preference = _mate_preference; } //@CHC
SetMatingDisplayA(int _mating_display_a)305   void SetMatingDisplayA(int _mating_display_a) { m_mating_display_a = _mating_display_a; } //@CHC
SetMatingDisplayB(int _mating_display_b)306   void SetMatingDisplayB(int _mating_display_b) { m_mating_display_b = _mating_display_b; } //@CHC
307 
308 
SetParentMuts(const cString & in_muts)309   void SetParentMuts(const cString & in_muts) { parent_muts = in_muts; }
SetMutSteps(const cString in_muts)310   void SetMutSteps(const cString in_muts) { m_genome.GetSequence().GetMutationSteps().Set(in_muts); }
311 
SetTaskOrder(const cString & in_order)312   void SetTaskOrder(const cString & in_order) { task_order = in_order; }
313 
314   // A set of NULL accessors to simplyfy automated accesses.
SetNULL(int idx,int dummy)315   void SetNULL(int idx, int dummy) { (void) dummy; }
SetNULL(int dummy)316   void SetNULL(int dummy) { (void) dummy; }
SetNULL(char dummy)317   void SetNULL(char dummy) { (void) dummy; }
SetNULL(double dummy)318   void SetNULL(double dummy) { (void) dummy; }
SetNULL(const cString & dummy)319   void SetNULL(const cString & dummy) { (void) dummy; }
SetNULL(cString dummy)320   void SetNULL(cString dummy) { (void) dummy; }
321 
322   // Accessors...
GetWorld()323   cWorld* GetWorld() { return m_world; }
324 
GetGenome()325   Genome& GetGenome() { return m_genome; }
GetGenome()326   const Genome& GetGenome() const { return m_genome; }
GetName()327   const cString& GetName() const { return name; }
GetAlignedSequence()328   const cString& GetAlignedSequence() const { return aligned_sequence; }
GetExecutedFlags()329   cString GetExecutedFlags() const { return executed_flags; }
330   cString GetAlignmentExecutedFlags() const;
GetInstExecutedCounts()331   const tArray<int>& GetInstExecutedCounts() const { return inst_executed_counts; }
332   int GetInstExecutedCount(int _inst_num) const;
333   cString DescInstExe(int _inst_id) const;
GetTag()334   const cString & GetTag() const { return tag; }
335 
GetViable()336   bool GetViable() const { return viable; }
337 
GetID()338   int GetID() const { return id_num; }
GetSource()339   int GetSource() const { return m_src; }
GetSourceArgs()340   const cString& GetSourceArgs() const { return m_src_args; }
GetParents()341   const cString& GetParents() const { return m_parent_str; }
GetParentID()342   int GetParentID() const { return parent_id; }
GetParent2ID()343   int GetParent2ID() const { return parent2_id; }
GetParentDist()344   int GetParentDist() const { return parent_dist; }
GetAncestorDist()345   int GetAncestorDist() const { return ancestor_dist; }
GetLineageLabel()346   int GetLineageLabel() const { return lineage_label; }
GetNumCPUs()347   int GetNumCPUs() const { return num_cpus; }
GetTotalCPUs()348   int GetTotalCPUs() const { return total_cpus; }
GetLength()349   int GetLength() const { return length; }
GetCopyLength()350   int GetCopyLength() const { return copy_length; }
GetExeLength()351   int GetExeLength() const { return exe_length; }
GetMinLength()352   int GetMinLength() const { return AvidaTools::Min(exe_length, copy_length); }
GetMerit()353   double GetMerit() const { return merit; }
GetCompMerit()354   double GetCompMerit() const { return merit / (double) GetMinLength(); }
GetGestTime()355   int GetGestTime() const { return gest_time; }
GetEfficiency()356   double GetEfficiency() const { return ((double) GetMinLength()) / (double) gest_time; }
GetFitness()357   double GetFitness() const { return fitness; }
GetDivType()358   double GetDivType() const { return div_type; }
GetMateID()359   int GetMateID() const { return mate_id; }
GetUpdateBorn()360   int GetUpdateBorn() const { return update_born; }
GetUpdateDead()361   int GetUpdateDead() const { return update_dead; }
GetDepth()362   int GetDepth() const { return depth; }
GetCells()363   const cString& GetCells() const { return m_cells; }
GetGestOffsets()364   const cString& GetGestOffsets() const { return m_gest_offsets; }
365 
GetParentMuts()366   const cString& GetParentMuts() const { return parent_muts; }
GetMutSteps()367   const cString GetMutSteps() const { const cMutationSteps& ms = m_genome.GetSequence().GetMutationSteps(); return ms.AsString(); }
368 
GetMatingType()369   int GetMatingType() const { return m_mating_type; }
GetMatePreference()370   int GetMatePreference() const { return m_mate_preference; }
GetMatingDisplayA()371   int GetMatingDisplayA() const { return m_mating_display_a; }
GetMatingDisplayB()372   int GetMatingDisplayB() const { return m_mating_display_b; }
373 
374   // Knockout accessors
375   int GetKO_DeadCount() const;
376   int GetKO_NegCount() const;
377   int GetKO_NeutCount() const;
378   int GetKO_PosCount() const;
379   int GetKO_Complexity() const;
380   int GetKOPair_DeadCount() const;
381   int GetKOPair_NegCount() const;
382   int GetKOPair_NeutCount() const;
383   int GetKOPair_PosCount() const;
384   int GetKOPair_Complexity() const;
385   const tArray< tArray<int> > & GetKO_TaskCounts() const;
386 
387   // Landscape accessors
GetFracDead()388   double GetFracDead() const  { CheckLand(); return m_land->GetProbDead(); }
GetFracNeg()389   double GetFracNeg() const { CheckLand(); return m_land->GetProbNeg(); }
GetFracNeut()390   double GetFracNeut() const { CheckLand(); return m_land->GetProbNeut(); }
GetFracPos()391   double GetFracPos() const { CheckLand(); return m_land->GetProbPos(); }
GetComplexity()392   double GetComplexity() const { CheckLand(); return m_land->GetComplexity(); }
GetLandscapeFitness()393   double GetLandscapeFitness() const { CheckLand(); return m_land->GetAveFitness(); }
394 
395 
396   // Phenotypic Plasticity accessors
GetNumPhenotypes()397   int    GetNumPhenotypes()     const { CheckPhenPlast(); return m_phenplast_stats->m_num_phenotypes; }
GetPhenotypicEntropy()398   double GetPhenotypicEntropy() const { CheckPhenPlast(); return m_phenplast_stats->m_phenotypic_entropy; }
GetMaximumFitness()399   double GetMaximumFitness()    const { CheckPhenPlast(); return m_phenplast_stats->m_max_fitness; }
GetMaximumFitnessFrequency()400   double GetMaximumFitnessFrequency() const {CheckPhenPlast(); return m_phenplast_stats->m_min_fit_frequency;}
GetMinimumFitness()401   double GetMinimumFitness()    const { CheckPhenPlast(); return m_phenplast_stats->m_min_fitness; }
GetMinimumFitnessFrequency()402   double GetMinimumFitnessFrequency() const {CheckPhenPlast(); return m_phenplast_stats->m_min_fit_frequency;}
GetAverageFitness()403   double GetAverageFitness()    const { CheckPhenPlast(); return m_phenplast_stats->m_avg_fitness; }
GetLikelyFrequency()404   double GetLikelyFrequency()  const { CheckPhenPlast(); return m_phenplast_stats->m_likely_frequency; }
GetLikelyFitness()405   double GetLikelyFitness()     const { CheckPhenPlast(); return m_phenplast_stats->m_likely_fitness; }
GetNumTrials()406   int    GetNumTrials()         const { CheckPhenPlast(); return m_phenplast_stats->m_recalculate_trials; }
GetViableProbability()407   double GetViableProbability()  const { CheckPhenPlast(); return m_phenplast_stats->m_viable_probability; }
GetTaskProbability(int task_id)408   double GetTaskProbability(int task_id) const {
409     if (task_id >= m_world->GetEnvironment().GetNumTasks()) return 0.0;
410     CheckPhenPlast();
411     return m_phenplast_stats->m_task_probabilities[task_id];
412   }
413   cString DescTaskProb(int task_id) const;
GetTaskProbabilities()414   tArray<double> GetTaskProbabilities() const { CheckPhenPlast(); return m_phenplast_stats->m_task_probabilities; }
415 
416 
GetFitnessRatio()417   double GetFitnessRatio() const { return fitness_ratio; }
GetEfficiencyRatio()418   double GetEfficiencyRatio() const { return efficiency_ratio; }
GetCompMeritRatio()419   double GetCompMeritRatio() const { return comp_merit_ratio; }
420 
GetTaskOrder()421   const cString & GetTaskOrder() const { return task_order; }
422   cString GetTaskList() const;
423 
GetHWType()424   int GetHWType() const { return m_genome.GetHardwareType(); }
GetInstSet()425   const cString& GetInstSet() const { return m_genome.GetInstSet(); }
GetSequence()426   cString GetSequence() const { return m_genome.GetSequence().AsString(); }
427   cString GetHTMLSequence() const;
428 
GetMapLink()429   cString GetMapLink() const {
430     return cStringUtil::Stringf("<a href=\"tasksites.%s.html\">Phenotype Map</a>", static_cast<const char*>(GetName()));
431   }
432 
GetNumTasks()433   int GetNumTasks() const { return task_counts.GetSize(); }
GetTaskCount(int task_id)434   int GetTaskCount(int task_id) const {
435     if (task_id >= task_counts.GetSize()) return 0;
436     return task_counts[task_id];
437   }
GetTaskCount(int task_id,const cStringList & args)438   int GetTaskCount(int task_id, const cStringList& args) const {
439     if (task_id >= task_counts.GetSize()) return 0;
440     if (args.HasString("binary")) return (task_counts[task_id] > 0);
441     return task_counts[task_id];
442   }
GetTaskCounts()443   const tArray<int>& GetTaskCounts() const { return task_counts; }
444   cString DescTask(int task_id) const;
445 
GetTaskQuality(int task_id)446   double GetTaskQuality(int task_id) const {
447 	  if (task_id >= task_counts.GetSize()) return 0;
448 	  return task_qualities[task_id];
449   }
GetTaskQualities()450   const tArray<double>& GetTaskQualities() const { return task_qualities; }
451 
452 
453   // number of different tasks performed
GetTotalTaskCount()454   int GetTotalTaskCount() const {
455   	int total_task_count = 0;
456   	for(int i = 0; i < task_counts.GetSize(); i++)
457   	{ if (task_counts[i] > 0) total_task_count++; }
458   	return total_task_count;
459   }
460 
461   // total number of tasks performed, including multiple performances
GetTotalTaskPerformanceCount()462   int GetTotalTaskPerformanceCount() const {
463   	int total_task_performance_count = 0;
464   	for(int i = 0; i < task_counts.GetSize(); i++)
465   	{ total_task_performance_count += task_counts[i]; }
466   	return total_task_performance_count;
467   }
468 
GetEnvInput(int input_id)469   int GetEnvInput(int input_id) const{
470     if (input_id >= m_env_inputs.GetSize()) return 0;
471     return m_env_inputs[input_id];
472   }
GetEnvInputs()473   const tArray<int>& GetEnvInputs() const{
474     return m_env_inputs;
475   }
DescEnvInput(int input_id)476   cString DescEnvInput(int input_id) const { return cStringUtil::Stringf("task.%d", input_id); }
477 
GetRBinTotal(int resource_id)478   double GetRBinTotal(int resource_id) const {
479     if (resource_id >= rbins_total.GetSize()) return -1;
480     return rbins_total[resource_id];
481   }
DescRTot(int resource_id)482   cString DescRTot(int resource_id) const { return cStringUtil::Stringf("Resource %d Total", resource_id);}
483 
GetRBinAvail(int resource_id)484   double GetRBinAvail(int resource_id) const {
485     if (resource_id >= rbins_avail.GetSize()) return -1;
486     return rbins_avail[resource_id];
487   }
DescRAvail(int resource_id)488   cString DescRAvail(int resource_id) const { return cStringUtil::Stringf("Resource %d Available", resource_id);}
489 
GetRSpec(int spec_id)490   int GetRSpec(int spec_id) const {
491     if (spec_id >= collect_spec_counts.GetSize() || spec_id < 0) return -1;
492     return collect_spec_counts[spec_id];
493   }
DescRSpec(int spec_id)494   cString DescRSpec(int spec_id) const { return cStringUtil::Stringf("# times specification %d used", spec_id);}
495 
496   // Comparisons...  Compares a genotype to the "previous" one, which is
497   // passed in, in one specified phenotype.
498   // Return values are:
499   //   -2 : Toggle; no longer has phenotype it used to...
500   //   -1 : Reduction in strength of phenotype
501   //    0 : Identical in phenotype
502   //   +1 : Improvement in phenotype
503   //   +2 : Toggle; phenotype now present that wasn't.
CompareNULL(cAnalyzeGenotype * prev)504   int CompareNULL(cAnalyzeGenotype* prev) const { (void) prev; return 0; }
CompareArgNULL(cAnalyzeGenotype * prev,int i)505   int CompareArgNULL(cAnalyzeGenotype* prev, int i) const { (void) prev; (void) i; return 0; }
CompareLength(cAnalyzeGenotype * prev)506   int CompareLength(cAnalyzeGenotype* prev) const
507   {
508     if (GetLength() < MIN_GENOME_LENGTH && prev->GetLength() > MIN_GENOME_LENGTH) return -2;
509     if (GetLength() > MIN_GENOME_LENGTH && prev->GetLength() < MIN_GENOME_LENGTH) return 2;
510     return 0;
511   }
CompareMerit(cAnalyzeGenotype * prev)512   int CompareMerit(cAnalyzeGenotype * prev) const { return NumCompare(GetMerit(), prev->GetMerit()); }
CompareCompMerit(cAnalyzeGenotype * prev)513   int CompareCompMerit(cAnalyzeGenotype * prev) const { return NumCompare(GetCompMerit(), prev->GetCompMerit()); }
CompareGestTime(cAnalyzeGenotype * prev)514   int CompareGestTime(cAnalyzeGenotype * prev) const
515   {
516     const int max_time = CalcMaxGestation();
517     const int cur_time = max_time - GetGestTime();
518     const int prev_time = max_time - prev->GetGestTime();
519     return NumCompare(cur_time, prev_time);
520   }
CompareEfficiency(cAnalyzeGenotype * prev)521   int CompareEfficiency(cAnalyzeGenotype * prev) const { return NumCompare(GetEfficiency(), prev->GetEfficiency()); }
CompareFitness(cAnalyzeGenotype * prev)522   int CompareFitness(cAnalyzeGenotype * prev) const { return NumCompare(GetFitness(), prev->GetFitness()); }
CompareTaskCount(cAnalyzeGenotype * prev,int task_id)523   int CompareTaskCount(cAnalyzeGenotype * prev, int task_id) const
524   {
525     return NumCompare(GetTaskCount(task_id), prev->GetTaskCount(task_id));
526   }
527 
528   /*
529   added to satisfy Boost.Python; the semantics are fairly useless --
530   equality of two references means that they refer to the same object.
531   */
532   bool operator==(const cAnalyzeGenotype& in) const { return &in == this; }
533 
534 
GetLink()535   cAnalyzeGenotypeLink& GetLink() { return m_link; }
GetParent()536   cAnalyzeGenotype* GetParent() { return GetLink().GetParent(); }
537 
LinkParent(cAnalyzeGenotype * parent)538   void LinkParent(cAnalyzeGenotype *parent) {
539     if (GetParent() && GetParent() != parent) GetParent()->GetLink().RemoveChild(this);
540     GetLink().SetParent(parent);
541     if (parent) parent->GetLink().AddChild(this);
542   }
543 
LinkChild(cAnalyzeGenotype & child)544   void LinkChild(cAnalyzeGenotype &child) { child.LinkParent(this); }
545 
UnlinkParent()546   void UnlinkParent() { LinkParent(0); }
547 
GetChildList()548   tList<cAnalyzeGenotype>& GetChildList() { return GetLink().GetChildList(); }
549 
UnlinkChildren()550   void UnlinkChildren()
551   {
552     tListIterator<cAnalyzeGenotype> it(GetChildList());
553     while (it.Next() != NULL) {
554       it.Get()->UnlinkParent();
555     }
556   }
557 
Unlink()558   void Unlink()
559   {
560     UnlinkParent();
561     UnlinkChildren();
562   }
563 
HasChild(cAnalyzeGenotype & child)564   bool HasChild(cAnalyzeGenotype &child) { return GetLink().FindChild(&child); }
565 
UnlinkChild(cAnalyzeGenotype & child)566   bool UnlinkChild(cAnalyzeGenotype &child)
567   {
568     if(HasChild(child)) {
569       child.UnlinkParent();
570       return true;
571     } else {
572       return false;
573     }
574   }
575 
576 
577   class ReadToken
578   {
579     friend class cAnalyzeGenotype;
580   private:
581     const cAnalyzeGenotype* m_ptr;
582 
583     ReadToken(const ReadToken&); // @not_implemented
584     ReadToken& operator=(const ReadToken&); // @not_implemented
585 
ReadToken(const cAnalyzeGenotype * ptr)586     inline ReadToken(const cAnalyzeGenotype* ptr) : m_ptr(ptr) { ; }
587 
Validate(const cAnalyzeGenotype * ptr)588     inline void Validate(const cAnalyzeGenotype* ptr) { assert(ptr == m_ptr); }
589 
590   public:
~ReadToken()591     ~ReadToken() { m_ptr->m_data->rwlock.ReadUnlock(); }
592   };
593 
594 };
595 
596 #endif
597