Structural deformable models
SpeciesDB.cpp
Go to the documentation of this file.
1 #ifdef WIN32
2 #include <windows.h>
3 #endif
4 #include <sstream>
5 #define _SP_DEFINE_
6 #include "SpeciesDB.h"
7 #include "Errors.h"
8 using namespace std;
9 
10 //-----------------------------------------------------------------------------
11 //SpeciesDB
12 
13 bool SpeciesDB::load(const char* filename)
14 {
15  clear();
16  ifstream ifs(filename);
17  ifs.close();
18  ParseFile pf(filename);
19  if(pf) {
20  try {
21  operator>>(pf, *this);
22  } catch (const IOException *e) {
23  cout << "Error loading " << filename << " message: "
24  << e->getMessage() << endl;
25  return false;
26  }
27  cout << "read " << size() << " entries from " << filename << endl;
28  m_Directory = pf.getPath();
29  m_Filename = pf.getFilename();
30  return true;
31  } else {
32  cout << "Error loading " << filename << endl;
33  return false;
34  }
35 }
36 
38 {
39  m_Selection.clear();
40  for(map<dword,Species>::const_iterator s=begin(); s!=end(); s++)
41  if(s->second.select(sp, how))
42  m_Selection.push_back(s->second.id);
43  m_CSel = m_Selection.begin();
44  return m_Selection.size();
45 }
46 
47 dword SpeciesDB::select(const std::list<dword>& idlist)
48 {
49  m_Selection = idlist;
50  m_CSel = m_Selection.begin();
51  return m_Selection.size();
52 }
53 
54 dword SpeciesDB::getSelectionID(int dir, bool wrap)
55 {
56  if(m_Selection.empty()) return 0;
57  if(dir==1) { // dir>0
58  m_CSel++;
59  if(m_CSel==m_Selection.end()) {
60  m_CSel = m_Selection.begin();
61  if(!wrap) return 0;
62  }
63  } else if(dir>1) {
64  m_CSel = m_Selection.end();
65  m_CSel--;
66  } else if(dir==-1) { // dir<0
67  if(m_CSel==m_Selection.begin()) {
68  m_CSel = m_Selection.end();
69  m_CSel--;
70  if(!wrap) return 0;
71  } else m_CSel--;
72  } else if(dir < -1) {
73  m_CSel = m_Selection.begin();
74  }
75  return *m_CSel;
76 }
77 
78 dword SpeciesDB::loadSelection(const std::string& fname,
79  std::list<dword>& sel)
80 {
81  ifstream is(fname.c_str());
82  if(is) {
83  sel.clear();
84  is >> ws;
85  while(is) {
86  dword selid=0;
87  is >> selid;
88  if(selid) sel.push_back(selid);
89  }
90  } else return 0;
91  return sel.size();
92 }
93 
94 dword SpeciesDB::writeSelection(const std::string& fname,
95  const std::list<dword>& sel)
96 {
97  ofstream os(fname.c_str());
98  if(os) {
99  for(list<dword>::const_iterator csel = sel.begin();
100  csel != sel.end(); csel++)
101  {
102  os << *csel << endl;
103  }
104  } else return 0;
105  return sel.size();
106 }
107 
109 {
110  Species s;
111  while(is) {
112  is >> s;
113  if(s.id) sp[s.id] = s;
114  }
115  return is;
116 }
117 
118 ostream& operator<<(ostream &os, const SpeciesDB &sp)
119 {
120  for(map<dword,Species>::const_iterator s=sp.begin(); s!=sp.end(); s++)
121  os << s->second << endl;
122  return os;
123 }
124 
125 //-----------------------------------------------------------------------------
126 //Species
127 
129 {
130  sp.clear();
131  sp.id = 0;
132  sp.m_Flags = 0;
133  while(is.getNextLine()) {
134  const string& token = is.getKey();
135  const string& value = is.getValue();
136  //cout << "token: " << token << " value: " << value << endl;
137  if(token == "species_id") {
138  if(sp.id != 0) { is.pushLine(); return is; }
139  istringstream(value) >> sp.id;
140  } else if(sp.id == 0) {
141  throw new IOException("record didn't start with 'species_id'");
142  } else if(token == "flags")
143  sp.readFlagString(value);
144  sp[token] = value;
145  }
146  return is;
147 }
148 
149 ostream& operator<<(ostream &os, const Species &sp)
150 {
151  int entry=0;
152  while(Species::SFIELDS[entry] != NULL) {
153  const string fields(Species::SFIELDS[entry]);
154  map<string,string>::const_iterator s=sp.find(fields);
155  if(sp.m_Flags && fields == "flags")
156  os << fields << " " << sp.getFlagString() << endl;
157  else if(s != sp.end()) os << s->first << " " << s->second << endl;
158  entry++;
159  }
160  return os;
161 }
162 
164  clear();
165  m_Flags = 0;
166  id = 0;
167 }
168 
169 bool Species::hasFlag(dword flag) const {
170  return m_Flags & flag;
171 }
172 
174  return m_Flags |= flag;
175 }
176 
178  return m_Flags &= ~flag;
179 }
180 
181 string Species::getFlagString() const {
182  dword bv=1;
183  string fs;
184  for(int b=0; b<32 && s_SPFLAGS[b]; b++,bv=bv<<1)
185  if(m_Flags&bv) fs += s_SPFLAGS[b];
186  return fs;
187 }
188 
189 dword Species::readFlagString(const string &flags) {
190  m_Flags = 0;
191  dword bv=1;
192  for(int b=0; b<32 && s_SPFLAGS[b]; b++,bv=(bv<<1))
193  if(flags.find(s_SPFLAGS[b]) != flags.npos) m_Flags |= bv;
194  return m_Flags;
195 }
196 
197 bool Species::select(const Species& sp, enum SpCompare how) const
198 {
199  for(map<string,string>::const_iterator rs=sp.begin();
200  rs != sp.end(); rs++)
201  {
202  map<string,string>::const_iterator s=find(rs->first);
203  if(s == end()) return false;
204  const string &lv = s->second;
205  const string &rv = rs->second;
206  if(s->first == "flags") {
207  for(string::const_iterator f=rv.begin(); f!=rv.end(); f++)
208  if(lv.find(*f)==lv.npos) return false;
209  } else {
210  switch(how) {
211  case CMP_EQUALS:
212  if(lv != rv) return false;
213  break;
214  case CMP_CONTAINS:
215  if(lv.find(rv) == lv.npos) return false;
216  break;
217  case CMP_LESSER:
218  if(lv > rv) return false;
219  break;
220  case CMP_GREATER:
221  if(lv < rv) return false;
222  break;
223  }
224  }
225  }
226  return true;
227 }
228 
230 {
231  dword scale=0;
232  const_iterator s=find("scale");
233  if(s!=end()) {
234  istringstream(s->second)>>scale;
235  }
236  return scale;
237 }
238 //-----------------------------------------------------------------------------
239 //DBSelector
240 
241 bool DBSelector::load(const char* filename)
242 {
243  ParseFile rf(filename);
244  while(rf) {
245  Species sp;
246  rf >> sp;
247  sp.erase("species_id");
248  m_Selectors.push_back(sp);
249  }
250  cout << m_Selectors.size() << " records read from " << filename << endl;
251  update();
252  return true;
253 }
254 
256 {
257  m_CSel = m_Selectors.begin();
258  nextSelector(0);
259 }
260 
261 bool DBSelector::nextSelection(int dir, bool wrap)
262 {
263  if(m_DB.empty()) return false;
264  if(!m_DB.getSelectionID()) {
265  map<dword,Species>::iterator n = m_DB.find(m_CSpecies.id);
266  if(n != m_DB.end()) {
267  if(dir>0) {
268  n++;
269  if(n == m_DB.end()) {
270  n = m_DB.begin();
271  if(!wrap) return false;
272  }
273  } else if(dir<0) {
274  if(n == m_DB.begin()) {
275  n = m_DB.end();
276  n--;
277  if(!wrap) return false;
278  } else n--;
279  }
280  m_CSpecies = n->second;
281  } else return false;
282  } else {
283  map<dword,Species>::iterator n = m_DB.find(
284  m_DB.getSelectionID(dir,wrap));
285  if(n != m_DB.end()) m_CSpecies = n->second;
286  else return false;
287  }
288  return true;
289 }
290 
291 bool DBSelector::nextSelector(int walkdir, bool wrap, dword mincount) {
292  bool ret = true;
293  list<Species>::iterator osel = m_Selectors.end();
294  while(m_CSel != osel)
295  {
296  if(osel == m_Selectors.end()) osel = m_CSel;
297  if(walkdir<0) {
298  if(m_CSel == m_Selectors.begin()) {
299  m_CSel = m_Selectors.end();
300  ret = wrap;
301  }
302  m_CSel--;
303  } else if(walkdir>0) {
304  m_CSel++;
305  if(m_CSel == m_Selectors.end()) {
306  m_CSel = m_Selectors.begin();
307  ret = wrap;
308  }
309  }
310  dword nsel = m_DB.select(*m_CSel);
311  if(nsel >= mincount) {
312  cout << nsel << " records found using selector:" << endl
313  << *m_CSel;
314  nextSelection(0);
315  osel = m_CSel;
316  } else {
317  cout << " no records found using selector:" <<endl<<*m_CSel;
318  }
319  }
320  if(m_CSel == m_Selectors.end()) {
321  m_CSel = m_Selectors.begin();
322  return false;
323  }
324  return ret;
325 }
ostream & operator<<(ostream &os, const SpeciesDB &sp)
Definition: SpeciesDB.cpp:118
#define NULL
Definition: simpletypes.h:9
dword readFlagString(const std::string &flags)
Definition: SpeciesDB.cpp:189
const std::string & getFilename() const
Definition: ParseFile.h:53
bool nextSelector(int walkdir=1, bool wrap=true, dword mincount=1)
Definition: SpeciesDB.cpp:291
dword id
Definition: SpeciesDB.h:41
STL namespace.
ParseFile & operator>>(ParseFile &is, SpeciesDB &sp)
Definition: SpeciesDB.cpp:108
bool hasFlag(dword flag) const
Definition: SpeciesDB.cpp:169
dword writeSelection(const std::string &fname) const
Definition: SpeciesDB.h:63
dword getSelectionID(int dir=0, bool wrap=true)
Definition: SpeciesDB.cpp:54
const std::string & getValue() const
Definition: ParseFile.h:57
static const char * SFIELDS[]
Definition: SpeciesDB.h:14
dword m_Flags
Definition: SpeciesDB.h:42
bool load(const char *filename)
Definition: SpeciesDB.cpp:241
dword setFlag(dword flag)
Definition: SpeciesDB.cpp:173
bool load(const char *filename)
Definition: SpeciesDB.cpp:13
const std::string & getPath() const
Definition: ParseFile.h:52
const std::string & getKey() const
Definition: ParseFile.h:56
const char * getMessage() const
Definition: Errors.h:41
dword loadSelection(const std::string &fname)
Definition: SpeciesDB.h:61
unsigned long dword
Definition: simpletypes.h:6
dword getScale() const
Definition: SpeciesDB.cpp:229
bool select(const Species &sp, enum SpCompare how=Species::CMP_CONTAINS) const
Definition: SpeciesDB.cpp:197
dword select(const Species &rhs, enum Species::SpCompare how=Species::CMP_CONTAINS)
Definition: SpeciesDB.cpp:37
std::string getFlagString() const
Definition: SpeciesDB.cpp:181
dword unsetFlag(dword flag)
Definition: SpeciesDB.cpp:177
bool nextSelection(int dir=1, bool wrap=true)
Definition: SpeciesDB.cpp:261
void pushLine(const std::string &line)
Definition: ParseFile.h:74
const bool getNextLine()
Definition: ParseFile.h:59
void reset()
Definition: SpeciesDB.cpp:163
void update()
should be called when data base has changed
Definition: SpeciesDB.cpp:255