#ifndef GRID_MASK_H
#define GRID_MASK_H
/*
* grid_mask.h
*
* This file is part of NEST.
*
* Copyright (C) 2004 The NEST Initiative
*
* NEST is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* NEST is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NEST. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "nest.h"
#include "topology_names.h"
#include "position.h"
#include "dictdatum.h"
#include "dictutils.h"
#include "topologymodule.h"
#include "mask.h"
namespace nest
{
/**
* Mask defined in terms of grid points rather than spacial
* coordinates. Only suitable for grid layers.
*/
template<int D>
class GridMask : public AbstractMask
{
public:
/**
* Parameters:
* columns - horizontal size in grid coordinates
* rows - vertical size in grid coordinates
* layers - z-size in grid coordinates (for 3D layers)
*/
GridMask(const DictionaryDatum& d);
bool inside(const std::vector<double_t> &) const
{ throw KernelException("Grid mask must be applied to a grid layer."); }
void set_anchor(const Position<D,int_t>&);
DictionaryDatum get_dict() const;
GridMask<D> * clone() const
{ return new GridMask(*this); }
/**
* @returns the name of this mask type.
*/
static Name get_name();
AbstractMask * intersect_mask(const AbstractMask &) const
{ throw KernelException("Grid masks can not be combined."); }
AbstractMask * union_mask(const AbstractMask &) const
{ throw KernelException("Grid masks can not be combined."); }
AbstractMask * minus_mask(const AbstractMask &) const
{ throw KernelException("Grid masks can not be combined."); }
Position<D,int_t> get_upper_left() const
{ return upper_left_; }
Position<D,int_t> get_lower_right() const
{ return lower_right_; }
protected:
Position<D,int_t> upper_left_;
Position<D,int_t> lower_right_;
};
template<int D>
GridMask<D>::GridMask(const DictionaryDatum& d)
{
int_t columns = getValue<long>(d, names::columns);
int_t rows = getValue<long>(d, names::rows);
if (D==3) {
int_t layers = getValue<long>(d, names::layers);
lower_right_ = Position<D,int_t>(columns,rows,layers);
} else if (D==2) {
lower_right_ = Position<D,int_t>(columns,rows);
} else {
throw BadProperty("Grid mask must be 2- or 3-dimensional.");
}
}
template<>
inline
Name GridMask<2>::get_name()
{
return names::grid;
}
template<>
inline
Name GridMask<3>::get_name()
{
return names::grid3d;
}
template<int D>
DictionaryDatum GridMask<D>::get_dict() const
{
DictionaryDatum d(new Dictionary);
DictionaryDatum maskd(new Dictionary);
def<DictionaryDatum>(d, get_name(), maskd);
def<long>(maskd, names::columns, lower_right_[0]-upper_left_[0]);
def<long>(maskd, names::rows, lower_right_[1]-upper_left_[1]);
if (D>=3) {
def<long>(maskd, names::layers, lower_right_[2]-upper_left_[2]);
}
return d;
}
template<int D>
void GridMask<D>::set_anchor(const Position<D,int_t>& anchor)
{
lower_right_ = lower_right_ - upper_left_ - anchor;
upper_left_ = -anchor;
}
} // namespace nest
#endif