1 /*
2  *  cPopulationCell.h
3  *  Avida
4  *
5  *  Called "pop_cell.hh" prior to 12/5/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 cPopulationCell_h
24 #define cPopulationCell_h
25 
26 #include "apto/core.h"
27 #include "avida/core/Sequence.h"
28 
29 #include <fstream>
30 #include <set>
31 #include <deque>
32 
33 #ifndef cMutationRates_h
34 #include "cMutationRates.h"
35 #endif
36 #ifndef tArray_h
37 #include "tArray.h"
38 #endif
39 #ifndef tList_h
40 #include "tList.h"
41 #endif
42 #include "cGenomeUtil.h"
43 
44 class cHardwareBase;
45 class cPopulation;
46 class cOrganism;
47 class cPopulationCell;
48 class cWorld;
49 
50 using namespace Avida;
51 
52 
53 class cPopulationCell
54 {
55   friend class cPopulation;
56 
57 private:
58   cWorld* m_world;
59 
60   cOrganism* m_organism;                    // The occupent of this cell.
61   cHardwareBase* m_hardware;
62 
63   tList<cPopulationCell> m_connections;  // A list of neighboring cells.
64   cMutationRates* m_mut_rates;           // Mutation rates at this cell.
65   tArray<int> m_inputs;                 // Environmental Inputs...
66 
67   int m_cell_id;           // Unique id for position of cell in population.
68   int m_deme_id;           // ID of the deme that this cell is part of.
69 
70   struct {
71     int contents;
72     int org_id;
73     int update;
74     int territory;
75     int current;
76     int forager;
77   } m_cell_data;         // "data" that is local to the cell and can be retrieaved by the org.
78 
79   int m_spec_state;
80 
81   bool m_migrant; //@AWC -- does the cell contain a migrant genome?
82 
83   // location in population
84   int m_x; //!< The x-coordinate of the position of this cell in the environment.
85   int m_y; //!< The y-coordinate of the position of this cell in the environment.
86 
87   // @WRE: Statistic for movement
88   int m_visits; // The number of times Avidians move into the cell
89 
90   void InsertOrganism(cOrganism* new_org, cAvidaContext& ctx);
91   cOrganism* RemoveOrganism(cAvidaContext& ctx);
92 
93 
94 public:
95   typedef std::set<cPopulationCell*> neighborhood_type; //!< Type for cell neighborhoods.
96 
cPopulationCell()97   cPopulationCell() : m_world(NULL), m_organism(NULL), m_hardware(NULL), m_mut_rates(NULL), m_migrant(false), can_input(false), can_output(false), m_hgt(0) { ; }
98   cPopulationCell(const cPopulationCell& in_cell);
~cPopulationCell()99   ~cPopulationCell() { delete m_mut_rates; delete m_hgt; }
100 
101   void operator=(const cPopulationCell& in_cell);
102 
103   void Setup(cWorld* world, int in_id, const cMutationRates& in_rates, int x, int y);
SetDemeID(int in_id)104   void SetDemeID(int in_id) { m_deme_id = in_id; }
105   void Rotate(cPopulationCell& new_facing);
106 
107   //@AWC -- This is, admittedly, a hack to get migration between demes working under local copy...
SetMigrant()108   void SetMigrant() {m_migrant = true;} //@AWC -- this cell will contain a migrant genome
UnsetMigrant()109   void UnsetMigrant() {m_migrant = false;} //@AWC -- unset the migrant flag
IsMigrant()110   bool IsMigrant() {return m_migrant;} //@AWC -- does this contain a migrant genome?
111 
GetOrganism()112   inline cOrganism* GetOrganism() const { return m_organism; }
GetHardware()113   inline cHardwareBase* GetHardware() const { return m_hardware; }
ConnectionList()114   inline tList<cPopulationCell>& ConnectionList() { return m_connections; }
115   //! Recursively build a set of cells that neighbor this one, out to the given depth.
116   void GetNeighboringCells(std::set<cPopulationCell*>& cell_set, int depth) const;
117   //! Recursively build a set of occupied cells that neighbor this one, out to the given depth.
118   void GetOccupiedNeighboringCells(std::set<cPopulationCell*>& occupied_cell_set, int depth) const;
119   void GetOccupiedNeighboringCells(Apto::Array<cPopulationCell*>& occupied_cells) const;
GetCellFaced()120   inline cPopulationCell& GetCellFaced() { return *(m_connections.GetFirst()); }
121   int GetFacing();  // Returns the facing of this cell.
122   int GetFacedDir(); // Returns the human interpretable facing of this org.
GetPosition(int & x,int & y)123   inline void GetPosition(int& x, int& y) const { x = m_x; y = m_y; } // Retrieves the position (x,y) coordinates of this cell.
GetPosition()124   inline std::pair<int,int> GetPosition() const { return std::make_pair(m_x,m_y); }
GetVisits()125   inline int GetVisits() { return m_visits; } // @WRE: Retrieves the number of visits for this cell.
IncVisits()126   inline void IncVisits() { m_visits++; } // @WRE: Increments the visit count for a cell
MutationRates()127   inline const cMutationRates& MutationRates() const { assert(m_mut_rates); return *m_mut_rates; }
MutationRates()128   inline cMutationRates& MutationRates() { assert(m_mut_rates); return *m_mut_rates; }
129 
GetInput(int input_cell)130   inline int GetInput(int input_cell) const { return m_inputs[input_cell]; }
GetInputs()131   inline const tArray<int>& GetInputs() const { return m_inputs; }
132   inline int GetInputAt(int& input_pointer);
GetInputSize()133   inline int GetInputSize() { return m_inputs.GetSize(); }
134   void ResetInputs(cAvidaContext& ctx);
135 
GetID()136   inline int GetID() const { return m_cell_id; }
GetDemeID()137   inline int GetDemeID() const { return m_deme_id; }
GetCellData()138   inline int GetCellData() const { return m_cell_data.contents; }
GetCellDataOrgID()139   inline int GetCellDataOrgID() const { return m_cell_data.org_id; }
GetCellDataUpdate()140   inline int GetCellDataUpdate() const { return m_cell_data.update; }
GetCellDataTerritory()141   inline int GetCellDataTerritory() const { return m_cell_data.territory; }
GetCellDataForagerType()142   inline int GetCellDataForagerType() const { return m_cell_data.forager; }
143   void UpdateCellDataExpired();
144   void SetCellData(int data, int org_id = -1);
145   void ClearCellData();
146 
GetSpeculativeState()147   inline int GetSpeculativeState() const { return m_spec_state; }
SetSpeculativeState(int count)148   inline void SetSpeculativeState(int count) { m_spec_state = count; }
DecSpeculative()149   inline void DecSpeculative() { m_spec_state--; }
150 
IsOccupied()151   inline bool IsOccupied() const { return m_organism != NULL; }
152 
153   double UptakeCellEnergy(double frac_to_uptake, cAvidaContext& ctx);
154 
155 // -------- Avatar support --------
156 private:
157   tSmartArray<cOrganism*> m_av_inputs;
158   tSmartArray<cOrganism*> m_av_outputs;
159 public:
GetNumAVInputs()160   inline int GetNumAVInputs() const { return m_av_inputs.GetSize(); }
GetNumAVOutputs()161   inline int GetNumAVOutputs() const { return m_av_outputs.GetSize(); }
GetNumAV()162   inline int GetNumAV() const { return GetNumAVInputs() + GetNumAVOutputs(); }
GetNumPredAV()163   inline int GetNumPredAV() const { return GetNumAVInputs(); }
GetNumPreyAV()164   inline int GetNumPreyAV() const { return GetNumAVOutputs(); }
165   void AddInputAV(cOrganism* org);
166   void AddOutputAV(cOrganism* org);
167   void RemoveInputAV(cOrganism* org);
168   void RemoveOutputAV(cOrganism* org);
HasInputAV()169   inline bool HasInputAV() const { return GetNumAVInputs() > 0; }
HasOutputAV()170   inline bool HasOutputAV() const { return GetNumAVOutputs() > 0; }
HasAV()171   inline bool HasAV() const { return (GetNumAVOutputs() > 0 || GetNumAVInputs() > 0); }
HasPredAV()172   inline bool HasPredAV() const { return GetNumAVInputs() > 0; }
HasPreyAV()173   inline bool HasPreyAV() const { return GetNumAVOutputs() > 0; }
174   bool HasOutputAV(cOrganism* org);
175   cOrganism* GetRandAV() const;
176   cOrganism* GetRandPredAV() const;
177   cOrganism* GetRandPreyAV() const;
178   tArray<cOrganism*> GetCellInputAVs();
179   tArray<cOrganism*> GetCellOutputAVs();
180   tArray<cOrganism*> GetCellAVs();
181 
182 // -------- Neural support --------
183 private:
184   bool can_input;
185   bool can_output;
186 public:
SetCanInput(bool input)187   void SetCanInput(bool input) { can_input = input; }
SetCanOutput(bool output)188   void SetCanOutput(bool output) { can_output = output; }
GetCanInput()189   bool GetCanInput() { return can_input; }
GetCanOutput()190   bool GetCanOutput() { return can_output; }
191 
192   // -------- HGT support --------
193 public:
194   typedef cGenomeUtil::fragment_list_type fragment_list_type; //!< Type for the list of genome fragments.
195   //! Diffuse genome fragments from this cell to its neighbors.
196   void DiffuseGenomeFragments();
197   //! Add fragments from the passed-in genome to the HGT fragments contained in this cell.
198   void AddGenomeFragments(cAvidaContext& ctx, const Sequence& genome);
199   //! Retrieve the number of genome fragments currently found in this cell.
200   unsigned int CountGenomeFragments() const;
201   //! Remove and return the front genome fragment.
202   Sequence PopGenomeFragment();
203   //! Retrieve the list of fragments from this cell.
204   fragment_list_type& GetFragments();
205   //! Clear all fragments from this cell, adjust resources as required.
206   void ClearFragments(cAvidaContext& ctx);
207 
208 private:
209   //! Contains HGT-related information for this cell.
210   struct HGTSupport {
211     // WARNING: the default operator= is used in cPopulationCell's copy ctor and operator=.
212     fragment_list_type fragments; //!< Fragments located in this cell.
213   };
214   HGTSupport* m_hgt; //!< Lazily-initialized pointer to the HGT support struct.
215   //! Initialize HGT support in this cell.
InitHGTSupport()216   inline void InitHGTSupport() { if(!m_hgt) { m_hgt = new HGTSupport(); } }
217   //! Is HGT initialized?
IsHGTInitialized()218   inline bool IsHGTInitialized() const { return m_hgt != 0; }
219 };
220 
GetInputAt(int & input_pointer)221 inline int cPopulationCell::GetInputAt(int& input_pointer)
222 {
223   input_pointer %= m_inputs.GetSize();
224   return m_inputs[input_pointer++];
225 }
226 
227 #endif
228