NEST  2.6.0,not_revisioned_source_dir@0
grid_layer.h
Go to the documentation of this file.
1 /*
2  * grid_layer.h
3  *
4  * This file is part of NEST.
5  *
6  * Copyright (C) 2004 The NEST Initiative
7  *
8  * NEST is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * NEST is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with NEST. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #ifndef GRID_LAYER_H
24 #define GRID_LAYER_H
25 
26 #include "layer.h"
27 
28 namespace nest
29 {
30 
33  template <int D>
34  class GridLayer: public Layer<D>
35  {
36  public:
38  typedef index mapped_type;
39  typedef std::pair<Position<D>,index> value_type;
41  typedef const value_type& const_reference;
42 
47  public:
52  layer_(layer), node_(), depth_(-1)
53  {}
54 
58  masked_iterator(const GridLayer<D> & layer, const Mask<D> &mask, const Position<D> &anchor, const Selector & filter);
59 
61 
67 
72  {
73  masked_iterator tmp = *this;
74  ++*this;
75  return tmp;
76  }
77 
81  bool operator==(const masked_iterator &other) const
82  { return (other.layer_.get_gid()==layer_.get_gid()) && (other.node_==node_) && (other.depth_==depth_); }
83  bool operator!=(const masked_iterator &other) const
84  { return (other.layer_.get_gid()!=layer_.get_gid()) || (other.node_!=node_) || (other.depth_!=depth_); }
85 
86  protected:
87 
90  const Mask<D> * mask_;
95  };
96 
98  Layer<D>()
99  {}
100 
101  GridLayer(const GridLayer &l):
102  Layer<D>(l),
103  dims_(l.dims_)
104  {}
105 
111  Position<D> get_position(index sind) const;
112 
119 
121 
123 
130  std::vector<index> get_nodes(Position<D,int_t> pos);
131 
133 
134  std::vector<std::pair<Position<D>,index> > get_global_positions_vector(Selector filter, const AbstractMask& mask, const Position<D>& anchor, bool allow_oversized);
135 
136  masked_iterator masked_begin(const Mask<D> &mask, const Position<D> &anchor, const Selector & filter);
137  masked_iterator masked_end();
138 
139  Position<D,index> get_dims() const;
140 
141  void set_status(const DictionaryDatum &d);
142  void get_status(DictionaryDatum &d) const;
143 
144  protected:
146 
147  template<class Ins>
148  void insert_global_positions_(Ins iter, const Selector& filter);
149  void insert_global_positions_ntree_(Ntree<D,index> & tree, const Selector& filter);
150  void insert_global_positions_vector_(std::vector<std::pair<Position<D>,index> > & vec, const Selector& filter);
151  void insert_local_positions_ntree_(Ntree<D,index> & tree, const Selector& filter);
152  };
153 
154  template <int D>
156  {
157  return dims_;
158  }
159 
160  template <int D>
162  {
163  Position<D,index> new_dims = dims_;
164  updateValue<long_t>(d, names::columns, new_dims[0]);
165  if (D>=2) updateValue<long_t>(d, names::rows, new_dims[1]);
166  if (D>=3) updateValue<long_t>(d, names::layers, new_dims[2]);
167 
168  index new_size = this->depth_;
169  for(int i=0;i<D;++i) {
170  new_size *= new_dims[i];
171  }
172 
173  if (new_size != this->global_size()) {
174  throw BadProperty("Total size of layer must be unchanged.");
175  }
176 
177  this->dims_ = new_dims;
178 
180  }
181 
182  template <int D>
184  {
186 
187  DictionaryDatum topology_dict = getValue<DictionaryDatum>((*d)[names::topology]);
188 
189  (*topology_dict)[names::columns] = dims_[0];
190  if (D>=2) (*topology_dict)[names::rows] = dims_[1];
191  if (D>=3) (*topology_dict)[names::layers] = dims_[2];
192  }
193 
194  template <int D>
196  {
197  lid %= this->global_size()/this->depth_;
198  Position<D,int_t> gridpos;
199  for(int i=D-1;i>0;--i) {
200  gridpos[i] = lid % dims_[i];
201  lid = lid / dims_[i];
202  }
203  assert(lid < dims_[0]);
204  gridpos[0] = lid;
205  return gridpos_to_position(gridpos);
206  }
207 
208  template <int D>
210  {
211  // grid layer uses "matrix convention", i.e. reversed y axis
212  Position<D> ext = this->extent_;
213  Position<D> upper_left = this->lower_left_;
214  if (D>1) {
215  upper_left[1] += ext[1];
216  ext[1] = -ext[1];
217  }
218  return upper_left + ext/dims_ * gridpos + ext/dims_ * 0.5;
219  }
220 
221  template <int D>
223  {
224  return lid_to_position(this->nodes_[sind]->get_lid());
225  }
226 
227  template <int D>
229  {
230  index lid = 0;
231 
232  // In case of periodic boundaries, allow grid positions outside layer
233  for(int i=0;i<D;++i) {
234  if (this->periodic_[i]) {
235  pos[i] %= int(dims_[i]);
236  if (pos[i]<0) pos[i] += dims_[i];
237  }
238  }
239 
240  for(int i=0;i<D;++i) {
241  lid *= dims_[i];
242  lid += pos[i];
243  }
244 
245  return lid;
246  }
247 
248  template <int D>
250  {
251  std::vector<index> gids;
252  index lid = gridpos_to_lid(pos);
253  index layer_size = this->global_size()/this->depth_;
254 
255  for(int d=0;d<this->depth_;++d) {
256  gids.push_back(this->gids_[lid + d*layer_size]);
257  }
258 
259  return gids;
260  }
261 
262  template <int D>
264  {
265  std::vector<Node*>::const_iterator nodes_begin;
266  std::vector<Node*>::const_iterator nodes_end;
267 
268  if (filter.select_depth()) {
269  nodes_begin = this->local_begin(filter.depth);
270  nodes_end = this->local_end(filter.depth);
271  } else {
272  nodes_begin = this->local_begin();
273  nodes_end = this->local_end();
274  }
275 
276  for(std::vector<Node*>::const_iterator node_it = nodes_begin; node_it != nodes_end; ++node_it) {
277 
278  if (filter.select_model() && ((*node_it)->get_model_id() != filter.model))
279  continue;
280 
281  tree.insert(std::pair<Position<D>,index>(lid_to_position((*node_it)->get_lid()), (*node_it)->get_gid()));
282  }
283  }
284 
285  template <int D>
286  template <class Ins>
287  void GridLayer<D>::insert_global_positions_(Ins iter, const Selector& filter)
288  {
289  index i = 0;
290  index lid_end = this->gids_.size();
291 
292  if (filter.select_depth()) {
293  const index nodes_per_layer = this->gids_.size() / this->depth_;
294  i = nodes_per_layer * filter.depth;
295  lid_end = nodes_per_layer * (filter.depth+1);
296  if ((i >= this->gids_.size()) or (lid_end > this->gids_.size()))
297  throw BadProperty("Selected depth out of range");
298  }
299 
300  Multirange::iterator gi = this->gids_.begin();
301  for (index j=0;j<i;++j) // Advance iterator to first gid at selected depth
302  ++gi;
303 
304  for(; (gi != this->gids_.end()) && (i < lid_end); ++gi, ++i) {
305 
306  if (filter.select_model() && ((int)this->net_->get_model_id_of_gid(*gi) != filter.model))
307  continue;
308 
309  *iter++ = std::pair<Position<D>,index>(lid_to_position(i), *gi);
310  }
311  }
312 
313  template <int D>
315  {
316  insert_global_positions_(std::inserter(tree, tree.end()), filter);
317  }
318 
319  template <int D>
320  void GridLayer<D>::insert_global_positions_vector_(std::vector<std::pair<Position<D>,index> > & vec, const Selector& filter)
321  {
322  insert_global_positions_(std::back_inserter(vec), filter);
323  }
324 
325  template <int D>
326  inline
328  {
329  return masked_iterator(*this, mask, anchor, filter);
330  }
331 
332  template <int D>
333  inline
335  {
336  return masked_iterator(*this);
337  }
338 
339  template <int D>
341  layer_(layer), mask_(&mask), anchor_(anchor), filter_(filter)
342  {
343  layer_size_ = layer.global_size()/layer.depth_;
344 
345  Position<D,int> ll;
346  Position<D,int> ur;
347  Box<D> bbox=mask.get_bbox();
348  bbox.lower_left += anchor;
349  bbox.upper_right += anchor;
350  for(int i=0;i<D;++i) {
351  if (layer.periodic_[i]) {
352  ll[i] = ceil((bbox.lower_left[i] - layer.lower_left_[i])*layer_.dims_[i]/layer.extent_[i] - 0.5);
353  ur[i] = round((bbox.upper_right[i] - layer.lower_left_[i])*layer_.dims_[i]/layer.extent_[i]);
354  } else {
355  ll[i] = std::min(index(std::max(ceil((bbox.lower_left[i] - layer.lower_left_[i])*layer_.dims_[i]/layer.extent_[i] - 0.5), 0.0)), layer.dims_[i]);
356  ur[i] = std::min(index(std::max(round((bbox.upper_right[i] - layer.lower_left_[i])*layer_.dims_[i]/layer.extent_[i]), 0.0)), layer.dims_[i]);
357  }
358  }
359  if (D>1) {
360  // grid layer uses "matrix convention", i.e. reversed y axis
361  int tmp = ll[1];
362  ll[1] = layer.dims_[1] - ur[1];
363  ur[1] = layer.dims_[1] - tmp;
364  }
365 
366  node_ = MultiIndex<D>(ll,ur);
367 
368  if (filter_.select_depth())
369  depth_ = filter_.depth;
370  else
371  depth_ = 0;
372 
373  if ((not mask_->inside(layer_.gridpos_to_position(node_)-anchor_)) or
374  (filter_.select_model() && (layer_.net_->get_model_id_of_gid(layer_.gids_[depth_*layer_size_]) != index(filter_.model))))
375  ++(*this);
376 
377  }
378 
379  template <int D>
380  inline
382  {
383  assert(depth_>=0);
384  return std::pair<Position<D>,index>(layer_.gridpos_to_position(node_),
385  layer_.gids_[layer_.gridpos_to_lid(node_) + depth_*layer_size_]);
386  }
387 
388  template <int D>
390  {
391  if (depth_ == -1) return *this; // Invalid (end) iterator
392 
393  if (not filter_.select_depth()) {
394  depth_++;
395  if (depth_ >= layer_.depth_) {
396  depth_ = 0;
397  } else {
398  if (filter_.select_model() && (layer_.net_->get_model_id_of_gid(layer_.gids_[depth_*layer_size_]) != index(filter_.model)))
399  return operator++();
400  else
401  return *this;
402  }
403  }
404 
405  do {
406  ++node_;
407 
408  if (node_ == node_.get_upper_right()) {
409  // Mark as invalid
410  depth_ = -1;
411  node_ = MultiIndex<D>();
412  return *this;
413  }
414 
415  } while (not mask_->inside(layer_.gridpos_to_position(node_)-anchor_));
416 
417  if (filter_.select_model() && (layer_.net_->get_model_id_of_gid(layer_.gids_[depth_*layer_size_]) != index(filter_.model)))
418  return operator++();
419 
420  return *this;
421  }
422 
423  template <int D>
424  std::vector<std::pair<Position<D>,index> > GridLayer<D>::get_global_positions_vector(Selector filter, const AbstractMask& mask, const Position<D>& anchor, bool)
425  {
426  std::vector<std::pair<Position<D>,index> > positions;
427 
428  const Mask<D>& mask_d = dynamic_cast<const Mask<D>&>(mask);
429  for(typename GridLayer<D>::masked_iterator mi = masked_begin(mask_d,anchor,filter); mi != masked_end(); ++mi) {
430  positions.push_back(*mi);
431  }
432 
433  return positions;
434  }
435 
436 } // namespace nest
437 
438 #endif
size_t index
Unsigned long type for enumerations.
Definition: nest.h:109
int int_t
Integer number with at least 16 bit.
Definition: nest.h:95
Definition: multirange.h:41
Position< D > lower_left_
lower left corner (minimum coordinates) of layer
Definition: layer.h:393
Definition: lockptrdatum.h:40
Position< D > anchor_
Definition: grid_layer.h:91
const Name d("d")
Specific to Izhikevich 2003.
Definition: nest_names.h:83
Layer with neurons placed in a grid.
Definition: grid_layer.h:34
const Name layer("layer")
Definition: topology_names.h:82
masked_iterator masked_end()
Definition: grid_layer.h:334
void get_status(DictionaryDatum &) const
Export properties of the layer by setting entries in the status dictionary.
Definition: layer_impl.h:79
An index into a multidimensional array.
Definition: position.h:304
std::pair< Position< D >, index > value_type
Definition: grid_layer.h:39
masked_iterator operator++(int)
Postfix increment operator.
Definition: grid_layer.h:71
std::vector< index > get_nodes(Position< D, int_t > pos)
Returns nodes at a given discrete layerspace position.
Definition: grid_layer.h:249
const Name layers("layers")
Definition: topology_names.h:81
value_type & reference
Definition: grid_layer.h:40
Contains rules for selecting nodes from a layer when connecting.
Definition: selector.h:36
Position< D > get_position(index sind) const
Get position of node.
Definition: grid_layer.h:222
Position< D > extent_
size of layer
Definition: layer.h:394
GridLayer(const GridLayer &l)
Definition: grid_layer.h:101
Position< D > gridpos_to_position(Position< D, int_t > gridpos) const
Definition: grid_layer.h:209
Iterator iterating over the nodes inside a Mask.
Definition: grid_layer.h:46
value_type operator*()
Definition: grid_layer.h:381
std::bitset< D > periodic_
periodic b.c.
Definition: layer.h:395
assert(pNet!=0)
const value_type & const_reference
Definition: grid_layer.h:41
const Mask< D > * mask_
Definition: grid_layer.h:90
void insert_local_positions_ntree_(Ntree< D, index > &tree, const Selector &filter)
Insert local position info into ntree.
Definition: grid_layer.h:263
index gridpos_to_lid(Position< D, int_t > pos) const
Definition: grid_layer.h:228
Abstract base class for masks with given dimension.
Definition: mask.h:90
A Ntree object represents a subtree or leaf in a Ntree structure.
Definition: ntree.h:49
Position< D > lid_to_position(index lid) const
Get position of node.
Definition: grid_layer.h:195
MultiIndex< D > node_
Definition: grid_layer.h:93
const Name anchor("anchor")
Definition: topology_names.h:50
bool select_depth() const
Definition: selector.h:58
void insert_global_positions_ntree_(Ntree< D, index > &tree, const Selector &filter)
Insert global position info into ntree.
Definition: grid_layer.h:314
Abstract base class for Layer of given dimension (D=2 or 3).
Definition: connection_creator.h:39
Selector filter_
Definition: grid_layer.h:92
void insert_global_positions_vector_(std::vector< std::pair< Position< D >, index > > &vec, const Selector &filter)
Insert global position info into vector.
Definition: grid_layer.h:320
const Name other("other")
Node type.
Definition: nest_names.h:216
iterator insert(Position< D > pos, const T &node)
Traverse quadtree structure from current ntree.
Definition: ntree_impl.h:362
GridLayer()
Definition: grid_layer.h:97
long_t model
The model to select, or -1 if all models are allowed.
Definition: selector.h:69
A box is defined by the lower left corner (minimum coordinates) and the upper right corner (maximum c...
Definition: position.h:289
const Name positions("positions")
Definition: topology_names.h:53
int_t layer_size_
Definition: grid_layer.h:89
void set_status(const DictionaryDatum &d)
Definition: grid_layer.h:161
masked_iterator masked_begin(const Mask< D > &mask, const Position< D > &anchor, const Selector &filter)
Definition: grid_layer.h:327
Position< D, index > dims_
number of nodes in each direction.
Definition: grid_layer.h:145
bool operator==(const masked_iterator &other) const
Iterators are equal if they point to the same node in the same layer.
Definition: grid_layer.h:81
const Name topology("topology")
Definition: topology_names.h:54
Exception to be thrown if a status parameter is incomplete or inconsistent.
Definition: exceptions.h:420
Position< D > upper_right
Definition: position.h:297
void get_status(DictionaryDatum &d) const
Definition: grid_layer.h:183
const Name min("min")
Definition: topology_names.h:74
const Name lid("lid")
Definition: topology_names.h:58
Position< D, index > get_dims() const
Definition: grid_layer.h:155
Position< D > key_type
Definition: grid_layer.h:37
const Name columns("columns")
Definition: topology_names.h:43
index mapped_type
Definition: grid_layer.h:38
size_t global_size() const
Returns total number of children.
Definition: subnet.h:276
long_t depth
The depth to select, or -1 if all depths are allowed.
Definition: selector.h:73
masked_iterator(const GridLayer< D > &layer)
Constructor for an invalid iterator.
Definition: grid_layer.h:51
int_t depth_
number of neurons at each position
Definition: layer.h:168
const Name max("max")
Definition: topology_names.h:75
Position< D > lower_left
Definition: position.h:296
const Name mask("mask")
Definition: topology_names.h:57
const Name rows("rows")
Number of rows in a layer or mask.
Definition: topology_names.h:42
void set_status(const DictionaryDatum &)
Change properties of the layer according to the entries in the dictionary.
Definition: layer_impl.h:58
const GridLayer< D > & layer_
Definition: grid_layer.h:88
virtual Box< D > get_bbox() const =0
The whole mask is inside (i.e., false everywhere outside) the bounding box.
Abstract base class for masks with unspecified dimension.
Definition: mask.h:41
int_t depth_
Definition: grid_layer.h:94
bool select_model() const
Definition: selector.h:53
bool operator!=(const masked_iterator &other) const
Definition: grid_layer.h:83
std::vector< std::pair< Position< D >, index > > get_global_positions_vector(Selector filter, const AbstractMask &mask, const Position< D > &anchor, bool allow_oversized)
Definition: grid_layer.h:424
iterator end()
Definition: ntree.h:261
masked_iterator & operator++()
Move the iterator to the next node within the mask.
Definition: grid_layer.h:389
void insert_global_positions_(Ins iter, const Selector &filter)
Definition: grid_layer.h:287