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