/* -*- mode: c++ -*- */
#ifndef __ScanPoint_h__
#define __ScanPoint_h__
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <string>
//////////////////////////////////////////////////////////////////////////
// class ScanVar
//
// Author: Carlos Lacasta
// Purpose:
// This class represents a scan variable. It contains
// information on the scan range, step and default value.
// It also defines the different types of scan variables.
//
//////////////////////////////////////////////////////////////////////////
class ScanVar
{
public:
enum ScanType
{ channel, pulse, threshold, trim, xposition, yposition, zposition,
angle1, angle2, angle3, user1, user2, user3, user4, thrs_trim, cal_dac};
private:
ScanType _type;
int _npoints;
double _first;
double _step;
double _default;
double _value;
// List of names
static std::vector<std::string> names;
void cpy(const ScanVar &s);
public:
ScanVar(ScanVar::ScanType tp, double frst = 0., double last = 1.,
double stp = 1., double dflt = 0.);
ScanVar(const ScanVar &s)
{
cpy(s);
}
ScanVar &operator=(const ScanVar &s)
{
if (this != &s)
cpy(s);
return *this;
}
ScanType type() const
{
return _type;
}
int n_points() const
{
return _npoints;
}
double first() const
{
return _first;
}
double last() const
{
return _first + (_npoints - 1)*_step;
}
double step() const
{
return _step;
}
double get_default() const
{
return _default;
}
double value() const
{
return _value;
}
void set_value(double x)
{
_value = x;
}
void set_n_points(int x)
{
_npoints = x;
}
void set_type(ScanType x)
{
_type = x;
}
void set_first(double x)
{
_first = x;
}
void set_step(double x)
{
_step = x;
}
void adjust(double first, double last, double step);
// I/O
std::ostream &dump(std::ostream &os);
std::istream &load(std::istream &is);
// global names
static int get_n_names()
{
return names.size();
}
static const std::string get_name(int x)
{
return names[x];
}
friend std::ostream &operator<<(std::ostream &, const ScanVar &);
};
inline std::ostream &operator<<(std::ostream &os, const ScanVar &v)
{
os << "Type "<< v._type<< " n. points "<< v._npoints<< " from "<< v._first
<< " step "<< v._step;
return os;
}
//////////////////////////////////////////////////////////////////////////
// ScanPoint
//
// Author: Carlos Lacasta
// Purpose:
// Represents a point in the scan. It is a collection of ScanVar
//
//////////////////////////////////////////////////////////////////////////
class ScanPoint
{
private:
std::string name;
std::vector<ScanVar> vvar;
void cpy(const ScanPoint &sc)
{
name = sc.name;
vvar.clear();
vvar = sc.vvar;
}
// Predicate used to find a ScanVar of a given type
class ftype
{
private:
ScanVar::ScanType type;
public:
ftype(ScanVar::ScanType tp) :
type(tp)
{
}
bool operator()(ScanVar &var)
{
return var.type() == type;
}
};
public:
ScanPoint() :
name("")
{
}
ScanPoint(std::string s) :
name(s)
{
}
ScanPoint(const ScanPoint &sc)
{
cpy(sc);
}
ScanPoint(const std::vector<ScanVar> &v) :
vvar(v)
{
}
void operator=(const ScanPoint &sc)
{
if ( this != &sc)
cpy(sc);
}
~ScanPoint()
{
vvar.clear();
}
void reset()
{
vvar.clear();
}
// I/O
std::ostream &dump(std::ostream &os);
std::istream &load(std::istream &is);
std::string get_name() const
{
return name;
}
void set_name(const std::string &s)
{
name = s;
}
std::vector<ScanVar>::iterator find_type(ScanVar::ScanType tp)
{
return find_if(vvar.begin(), vvar.end(), ftype(tp));
}
void remove_var(ScanVar::ScanType tp)
{
std::vector<ScanVar>::iterator ip = find_type(tp);
if (ip != vvar.end() )
vvar.erase(ip);
}
// Adds or modifies a variable
void add_var(ScanVar &v)
{
std::vector<ScanVar>::iterator ip = find_type(v.type() );
if (ip == vvar.end() )
vvar.push_back(v);
else
*ip = v;
}
int nvar() const
{
return vvar.size();
}
int npoints() const;
std::vector<ScanVar>::iterator end()
{
return vvar.end();
}
std::vector<ScanVar>::iterator begin()
{
return vvar.begin();
}
std::vector<ScanVar>::const_iterator end() const
{
return vvar.end();
}
std::vector<ScanVar>::const_iterator begin() const
{
return vvar.begin();
}
const std::vector<ScanVar> &operator()() const
{
return vvar;
}
friend std::ostream &operator<<(std::ostream &, const ScanPoint &);
static int FillList(std::vector<ScanVar>::iterator from,
std::vector<ScanVar>::iterator to, ScanPoint &sc,
std::vector<ScanPoint> &lst);
};
typedef std::map<std::string, ScanPoint> ScanListType;
class ScanList : protected ScanListType
{
private:
void cpy(const ScanList &s);
public:
using ScanListType::iterator;
using ScanListType::const_iterator;
using ScanListType::begin;
using ScanListType::end;
using ScanListType::find;
using ScanListType::empty;
using ScanListType::erase;
using ScanListType::size;
ScanList()
{
}
ScanList(const ScanList &s)
{
cpy(s);
}
void operator=(const ScanList &s)
{
if (this != &s)
cpy(s);
}
void remove_point(const std::string &name)
{
ScanList::iterator ip = find(name);
if (ip!=end())
erase(ip);
}
void add_point(const std::string &name, const ScanPoint &pt)
{
remove_point(name);
(*this)[name] = pt;
}
// I/O
std::ostream &dump(std::ostream &os);
std::istream &load(std::istream &is);
};
inline std::ostream &operator<<(std::ostream &os, const ScanPoint &sc)
{
std::vector<ScanVar>::const_iterator ip;
for (ip = sc.vvar.begin(); ip != sc.vvar.end(); ++ip)
os << (*ip)<< std::endl;
return os;
}
#endif