Structural deformable models
Brain.cpp
Go to the documentation of this file.
1 #include <fxkeys.h>
2 #include <algorithm>
3 #include <functional>
4 #include <sstream>
5 #include <cstdint>
6 
7 #include "Brain.h"
8 #include "ParseFile.h"
9 
10 #include "deform.h"
11 #include "Data.h"
12 #include "SensorSet.h"
13 #include "mathutil.h"
14 #include "utils.h"
15 #include "glutils.h"
16 
17 //#include "camgraph/gprocess.h"
18 
19 using namespace std;
20 
21 #undef __SHAPEWEIGHT
22 #define __SHAPEWEIGHT 0.1
23 #define MERGENAME "all"
24 
25 //--------------------------------------
26 
27 Brain::Brain() : m_DBSelector(m_DB), m_TimeStep(TIMESTEP), m_TimeScale(1),
28  m_UpdateAllModels(false), m_DrawOwnState(false),
29  m_SModel(*this)
30 {
31  m_Data = std::make_shared<Dataset>();
32  m_BrowseData = std::make_shared<Dataset>();
33  m_Done = false;
34  m_Sensors.addSensor("d0", m_Data);
35  m_Geom = new Model(m_Data, &m_Sensors);
36  m_CStates = new vector<Model*>; //&m_Instances[m_Geom->getName()];
38  m_CStates->push_back(m_Geom);
39  m_CurState=0;
40  m_DesignMode = false;
41  m_ImmediateData = false;
42  for(int i = 0; i<DO_LAST; i++) m_ThreadActive[i] = false;
44 }
45 
47 {
48  for(int i = 0; i<DO_LAST; i++)
49  if(m_ThreadActive[i]) m_RunMutex[i].lock();
50  // will be unlocked by the thread
51  for(int i = 0; i<DO_LAST; i++)
52  if(m_ThreadActive[i]) m_RunMutex[i].lock();
53  for(int i = 0; i<DO_LAST; i++)
54  if(m_ThreadActive[i]) m_RunMutex[i].unlock();
55  m_GeomMutex.lock();
56 // for(map<string, vector<Model*> >::iterator ii = m_Instances.begin();
57 // ii != m_Instances.end(); ii++)
58 // {
59 // changeModel(ii->first);
60  if(m_CStates) {
61  for(vector<Model*>::iterator gi=m_CStates->begin();
62  gi!=m_CStates->end(); gi++)
63  {
64  delete *gi;
65  }
66  delete m_CStates;
67  m_CStates = NULL;
68  }
69 // }
70 // for(map<string,Model*>::iterator gi=m_Prototypes.begin();
71 // gi!=m_Prototypes.end(); gi++)
72 // {
73 // delete gi->second;
74 // }
75 }
76 
77 const Dataset& Brain::getData() const
78 {
79  return *m_BrowseData;
80 }
81 
83 {
84  return *m_Data;
85 }
86 
87 bool Brain::load(const char *bfile) {
88  ParseFile is(bfile);
89  if(is) {
90  cout << "loading " << bfile << endl;
91  string sbpath = is.getPath();
92  m_CSpecies.reset();
93  //try?
94  while(is.getNextLine()) {
95  string param = is.getKey();
96  if(param == "db") {
97  if(!loadDB((sbpath+is.getValue()).c_str())) {
98  cerr << "Couldn't load data base " << is.getValue()<< endl;
99  return false;
100  }
101  } else if(param == "dbsel") {
102  if(!loadDBSelector((sbpath+is.getValue()).c_str())) {
103  cerr<<"Couldn't load data base selector "
104  <<is.getValue()<<endl;
105  return false;
106  }
107  } else if(param == "data") {
108  if(!loadData((sbpath+is.getValue()).c_str())) {
109  cerr << "Couldn't load data set " <<is.getValue()<< endl;
110  return false;
111  }
112  } else if(param == "model") {
113  cout << "loading model " << is.getValue() << endl;
114  if(!loadModel((sbpath+is.getValue()).c_str())) {
115  cerr << "Couldn't load model file " <<is.getValue()<< endl;
116  return false;
117  }
118  } else if(param == "structure") {
119  cout << "loading structure " << is.getValue() << endl;
120  vuLock glock(m_GeomMutex);
121  if(!m_SModel.load((sbpath+is.getValue()).c_str())) {
122  cerr << "Couldn't load structure description "
123  << (sbpath+is.getValue()) << endl;
124  return false;
125  }
126  cout << m_SModel << endl;
127 // list<Model*> ml;
128 // if(getAllModels( back_inserter( ml ) )) {
129 // for(list<Model*>::iterator gi=ml.begin();
130 // gi != ml.end(); gi++)
131 // (*gi)->reattachSensors();
132 // }
133 // m_Search.reattachSensors();
135  } else if(param == "searcher") {
136  cout << "configuring searcher from " << is.getValue() << endl;
137  ParseFile pf((sbpath+is.getValue()).c_str());
138  if(!getSearchPara().read(pf)) {
139  cerr << "Couldn't searcher config "<<is.getValue()<< endl;
140  return false;
141  }
142  getSearchPara().write(cout);
143  } else if(param.size()>0) {
144  is.setParseError("Error parsing brain description.");
145  cerr << is.getErrorMsg() << endl;
146  return false;
147  }
148  } // of while getline
149  if(!(*m_Geom)) {
151  if(cs) cout << "current structure is: " << cs.getName() << endl;
152  if(!cs.getRefModel(m_CSpecies.id, *m_Geom))
153  *m_Geom = cs.getModel();
154  }
155  cout << "finished loading " << bfile << endl;
156  } else {
157  cerr << "Could not open " << bfile << endl;
158  return false;
159  }
160  return true;
161 }
162 
163 bool Brain::loadModel(const char *filename)
164 {
165  vuLock glock(m_GeomMutex);
166  //Model *model = new Model(&m_Data, &m_Sensors);
167  bool ret=m_Geom->readFile(filename);
168  //changeModel(model->getName());
169  //m_CStates->push_back(model);
170  //m_Geom = model;
171  //m_CurState = m_CStates->size()-1;
172 // if(ret) {
173 // m_Prototypes[m_Geom->getName()] = new Model(*m_Geom);
174 // //remove initial dummy model
175 // string dmn = Model().getName();
176 // if(m_Instances.count(dmn)) {
177 // for(vector<Model*>::iterator mi=m_Instances[dmn].begin();
178 // mi != m_Instances[dmn].end(); mi++)
179 // delete *mi;
180 // m_Instances.erase(dmn);
181 // }
182 // }
183 // list<Model*> ml;
184 // if(getAllModels( back_inserter( ml ) )) {
185 // for(list<Model*>::iterator gi=ml.begin(); gi != ml.end(); gi++)
186 // if(*gi != m_Geom) (*gi)->reattachSensors();
187 // }
188 // m_SModel.reattachSensors();
189 // m_Search.reattachSensors();
191  setupSearch();
192  return true;
193 }
194 
195 bool Brain::loadDB(const char *filename)
196 {
197  if(!m_DB.load(filename)) return false;
200  return true;
201 }
202 
203 bool Brain::loadDBSelector(const char *filename)
204 {
205  if(!m_DBSelector.load(filename)) return false;
207  return true;
208 }
209 
210 bool Brain::loadSpecies(const Species& spec)
211 {
212  m_CSpecies = spec;
213  map<string,string>::const_iterator in = spec.find("image");
214  if(in == spec.end()) return false;
215 
216  string msg = "species_id: ";
217  stringstream sstrm;
218  sstrm << m_CSpecies.getScale();
219  string number;
220  sstrm >> number;
221  msg += m_CSpecies["species_id"] + " image: " + m_CSpecies["image"]
222  + " flags: " + m_CSpecies.getFlagString()
223  + " scale (pixels per mm): "+number;
224  setStatusText(msg.c_str());
225  setTitle(m_CSpecies["name"].c_str());
226 
227  return loadData((m_DB.getDirectory()+"/"+in->second).c_str(),
228  spec.getScale());
229 }
230 
231 bool Brain::changeModel(const string &mname) {
232  return false;
233 #if 0
234  m_CurPrototype = mname;
235  m_CStates = &m_Instances[mname];
236  switchState(0);
237  return true;
238 #else
239  map<string, vector<Model*> >::iterator fs =
240  m_Instances.find(mname);
241  if(fs != m_Instances.end()) {
242 // iterator map<string, vector<Model*> >::iterator os =
243 // m_Instances.find(m_CurPrototype);
244 // if(os->first) {
245 // os->second = m_CStates;
246 // }
247  m_CStates = &fs->second;
248  m_CurPrototype = mname;
249  switchState(0);
250  return true;
251  } else {
252  m_Instances[mname].resize(0);
253  m_CStates = &m_Instances[mname];
254  m_CurPrototype = mname;
255  //m_Geom is invalid now!
256  return false;
257  }
258 #endif
259 }
260 
262 {
263  return false;
264  static const string mergename(MERGENAME);
265  if(m_Instances.size() <= 1) return false;
266  if(changeModel(mergename)) {
267  for(vector<Model*>::iterator mi=m_CStates->begin();
268  mi!=m_CStates->end(); mi++)
269  delete *mi;
270  }
271  int msize=0;
272  for(map<string, vector<Model*> >::iterator ii = m_Instances.begin();
273  ii != m_Instances.end(); ii++)
274  msize+=ii->second.size();
275  m_CStates->reserve(msize);
276  for(map<string, vector<Model*> >::iterator ii = m_Instances.begin();
277  ii != m_Instances.end(); ii++)
278  {
279  if(ii->first != mergename)
280  for(vector<Model*>::iterator mi=ii->second.begin();
281  mi!=ii->second.end(); mi++)
282  m_CStates->push_back(new Model(**mi));
283  }
284  switchState(0);
285  return true;
286 }
287 
288 bool Brain::loadData(const char *filename, dword ppmm)
289 {
290  vuLock dlock(m_DataMutex);
291  if(!ppmm) ppmm = m_CSpecies.getScale();
292  bool ret = m_BrowseData->load(filename, ppmm);
293  if(ret) {
295  else if(m_Data->initialized()) m_Data->clear();
296  }
297  return ret;
298 }
299 
301 {
302  if(m_Data->getFilename() == m_BrowseData->getFilename()) {
303  cout << "dataset already attached" << endl;
304  return;
305  }
306  cout << "attaching data..." << endl;
307  m_Data->copyData(*m_BrowseData);
308  list<Model*> ml;
309  if(getAllModels(back_inserter(ml))) {
310  for(list<Model*>::iterator m=ml.begin(); m!=ml.end(); m++)
311  (*m)->adaptDataScale();
312  }
314  setupSearch();
315  cout << "attaching data done." << endl;
316 }
317 
318 #define EXIT_THREAD(t) \
319  { \
320  m_ThreadActive[t] = false; \
321  m_RunMutex[t].unlock(); \
322  }
323 
324 #define CHECK_THREAD(t) \
325  { \
326  m_RunMutex[t].unlock(); \
327  vuThread::usleep(100); \
328  if(!m_RunMutex[t].trylock()) { \
329  EXIT_THREAD(t); \
330  break; \
331  } \
332  }
333 
334 void Brain::run(int whatsup, void* data)
335 {
336  unsigned long lastticks = 0;
337  static int anastate = 0;
338  switch(whatsup) {
339  case DO_ANIMATE:
340  if(m_ThreadActive[DO_ANIMATE]) break;
341  m_ThreadActive[DO_ANIMATE] = true;
342  while(m_RunMutex[DO_ANIMATE].trylock()) {
343  double dt;
344  unsigned long nowticks = getMilliSeconds();
345  if(!lastticks) {
346  lastticks = nowticks;
347  dt = 0.0;
348  } else {
349  dt = (nowticks-lastticks)*0.001; //seconds
350  }
351  if(dt>m_TimeStep) {
352  vuLock glock(m_GeomMutex);
353  vuLock dlock(m_DataMutex);
354  if(dt>2*m_TimeStep) dt = m_TimeStep;
355  lastticks=nowticks;
356  if(m_Data->getDim1Size()) {
357  evolve(dt*m_TimeScale);
358  }
359  if(m_UpdateAllModels) {
360  for(vector<Model*>::iterator m = m_CStates->begin();
361  m!=m_CStates->end(); m++)
362  {
363  (*m)->updateParticles(dt*m_TimeScale);
364  }
365  }
366  }
369  }
370  m_ThreadActive[DO_ANIMATE] = false;
372  break;
373  case DO_NOTHING:
374  if(m_ThreadActive[DO_NOTHING]) break;
375  m_ThreadActive[DO_NOTHING] = true;
376  while(m_RunMutex[DO_NOTHING].trylock()) {
377  usleep((dword)(1000*m_TimeStep));
379  }
380  m_ThreadActive[DO_NOTHING] = false;
382  break;
383  case DO_ANALYSIS:
384  {
385  anastate = (int)(intptr_t)data;
386  if(m_ThreadActive[DO_ANALYSIS]) break;
387  m_ThreadActive[DO_ANALYSIS] = true;
388  if(!m_RunMutex[DO_ANALYSIS].trylock()) {
389  EXIT_THREAD(DO_ANALYSIS);
390  break;
391  } // now we have locked the runmutex
393  if(m_DBSelector.nextSelection(-2)) {
394  ofstream os("structmatch.txt",ios::app);
395  os << "checking structural matches" << endl << endl;
396  do{
398  m_GeomMutex.lock();
401  CHECK_THREAD(DO_ANALYSIS);
402  cout << "hello" << endl;
403  m_GeomMutex.lock();
406  //do analysis here (anahere)
407  os << "species id: " << m_CSpecies.id
408  << " name: " << m_CSpecies["name"] << endl;
409  unsigned long nowticks = getMilliSeconds();
411  while(!m_SModel.searchDone()) {
412  CHECK_THREAD(DO_ANALYSIS); // sleep
413  }
414  const map<string,StructPath>& interp =
416  os << "best interpretation: "
417  << m_SModel.getBestInterpretation() << endl;
418  for(map<string,StructPath>::const_iterator ip =
419  interp.begin(); ip != interp.end(); ip++)
420  {
421  os << ip->first << ": "
422  << ip->second.getRelGoodness() << endl;
423  }
424  os << "time: " << (getMilliSeconds()-nowticks)*0.001
425  << endl;
426  cout << "best interpretation: "
427  << m_SModel.getBestInterpretation() << endl;
428  //output results
429  }
430  if(anastate == -1) { EXIT_THREAD(DO_ANALYSIS); break; }
431  } while(m_DBSelector.nextSelection(1,false));
432  }
433  EXIT_THREAD(DO_ANALYSIS);
434  cout << "analysis terminated" << endl;
435  break;
436  }
437  default:
438  break;
439  }
440 }
441 
442 bool Brain::triggerTest(int mx, int my, int what) {
443  static int keymode=0;
444  static int curpid=-1;
445  static string command;
446  static list<vector<float> > colors;
447  switch(keymode) {
448  case 1:
449  {
450  vuLock glock(m_GeomMutex);
451  keymode = 0;
452  return m_Search.triggerTest(mx, my, what);
453  }
454  break;
455  case 2:
456  if(what == KEY_Return) {
457  cout << "command: " << command << endl;
458  command = "";
459  keymode = 1;
460  } else {
461  command += char(what);
462  cout << char(what) << flush;
463  }
464  return true;
465  break;
466  case 3:
467  {
468  vuLock glock(m_GeomMutex);
469  keymode = 0;
470  bool ret = m_SModel.triggerTest(mx, my, what);
471  return ret;
472  }
473  break;
474  }
475  switch(what) {
476  case KEY_X:
477  cout << "type command: " << flush;
478  keymode = 2;
479  break;
480  case KEY_h:
481  if(keymode) {
482  if(keymode == 128) {
483  dword cnt = 0;
484  ofstream os("antcol.dat",ios::app);
485  for(list< vector<float> >::const_iterator col=
486  colors.begin(); col != colors.end(); col++, cnt++)
487  {
488  for(vector<float>::const_iterator c=col->begin();
489  c!=col->end(); c++)
490  os << *c << " ";
491  os << endl;
492  }
493  os << endl;
494  cout << "wrote " << cnt << " colors to antcol.dat" << endl;
495  }
496  keymode = 0;
497  colors.clear();
498  } else keymode = 128;
499  break;
500  case KEY_j:
501  if(keymode) {
502  if(keymode == 129) {
503  ofstream os("antbg.dat",ios::app);
504  dword cnt=0;
505  for(list< vector<float> >::const_iterator col=
506  colors.begin(); col != colors.end(); col++, cnt++)
507  {
508  for(vector<float>::const_iterator c=col->begin();
509  c!=col->end(); c++)
510  os << *c << " ";
511  os << endl;
512  }
513  os << endl;
514  cout << "wrote " << cnt << " colors to antbg.dat" << endl;
515  }
516  keymode = 0;
517  colors.clear();
518  } else keymode = 129;
519  case KEY_H: //mouse move
520  if(keymode == 128 || keymode == 129) {
521  vuLock dlock(m_DataMutex);
522  vector<float> col(m_BrowseData->getMValue(mx,my));
523  for(vector<float>::const_iterator c=col.begin();
524  c!=col.end(); c++)
525  cout << " " << *c;
526  cout << endl;
527  colors.push_back(col);
528  }
529  if(m_DesignMode) {
530  vuLock glock(m_GeomMutex);
531  int HLNode = m_Geom->nearestNode(Point(mx,my));
532  m_Geom->setHLNode(HLNode);
533  setStatusText(string("node id: ") + toString(HLNode+1));
534  } else m_Geom->setHLNode(-1);
535  break;
536  case KEY_Control_L: //mouse click
537  if(!m_DesignMode) {
538  vuLock glock(m_GeomMutex);
539  m_Geom->translate(Point(mx,my)-m_Geom->getCenter());
540  } else {
541  vuLock glock(m_GeomMutex);
542  if(m_Geom->getHLNode() >= 0) {
544  toggleState(Node::ST_SELECT);
545  }
546 #if 0
547  cout<<"adding edge ["<<curpid+1
548  <<" "<<cnid+1<<"]"<<endl;
549  m_Geom->addEdge(curpid,cnid);
551 #endif
552  }
553  break;
554  case KEY_Return:
555  {
556  vuLock dlock(m_DataMutex);
558  }
559  break;
560  case KEY_r: // r
561  {
562  //TRACE(m_Geom->getStdRadius());
564  break;
565  }
566  case KEY_d: // d
567  {
568  keymode = 3;
569  cout << "smodel key: " << endl;
570 // vuLock glock(m_GeomMutex);
571 // duplicateState();
572 // TRACE(m_CStates->size() << " models");
573  }
574  break;
575  case KEY_space: // space
576  {
577  static bool ison = true;
578  ison = !ison;
579  toggleUpdateForAll(ison);
580  }
581  break;
582  case KEY_s: // s
583  {
584  keymode = 1;
585  cout << "searcher key: " << endl;
586  break;
587  }
588  break;
589  case KEY_S: //S
591  break;
592  case KEY_q:
594  break;
595  case KEY_a:
597  break;
598  case KEY_A:
600  break;
601  case KEY_z:
603  break;
604  case KEY_Z:
605  setupSearch();
606  break;
607  case KEY_W:
608  {
609  vuLock glock((vuMutex&)m_GeomMutex);
611  break;
612  }
613  case KEY_Right: //right
614  {
615  vuLock glock(m_GeomMutex);
616  switchState((m_CurState+1)%m_CStates->size());
617  cout << "quality of fit "<<(m_Geom->getQualityOfFit()) << endl;
618  cout << " flags: " << hex << m_Geom->getFlags() << endl << dec;
619  }
620  break;
621  case KEY_Left: //left
622  {
623  vuLock glock(m_GeomMutex);
624  switchState((int(m_CurState)-1)%m_CStates->size());
625  cout << "quality of fit "<<(m_Geom->getQualityOfFit()) << endl;
626  cout << " flags: " << hex << m_Geom->getFlags() << endl << dec;
627  }
628  break;
629  case KEY_l: //l
630  if(m_Geom->getSelectedNodesN()) {
632  } else m_Geom->adaptRestLength(0.2);
633  break;
634  case KEY_L:
635  {
636  vuLock glock(m_GeomMutex);
638  break;
639  }
640  case KEY_k: //k
642  break;
643  case KEY_p: //p
644  m_Geom->adaptProportion(0.3);
645  break;
646  case KEY_D: //D
647  {
648  vuLock glock(m_GeomMutex);
649  float lqof,hqof;
650  getQualityRange(lqof,hqof,__SHAPEWEIGHT);
651  float qth = hqof*0.7;
652  TRACE("quality th " <<qth);
653 #if 1
654 //#ifndef DISTRIBUTE_ALL_PROTOTYPES
655 // Model *pt = m_Prototypes[m_CurPrototype];
656  Model *pt = m_Geom;
657  cout << "distributing " << pt->getName() << endl;
659  int nm=0, ni=100;
660  while(nm<50 && --ni)
661  nm+=distributeModel(*pt,0,qth,true);
662 #else
663  for(map<string,Model*>::iterator gi=m_Prototypes.begin();
664  gi!=m_Prototypes.end(); gi++)
665  {
666  cout << "distributing " << gi->second->getName() << endl;
667  gi->second->setShapeWeight(__SHAPEWEIGHT);
668  int nm=0, ni=100;
669  while(nm<50 && --ni)
670  nm+=distributeModel(*gi->second,0,qth,true);
671  }
672 #endif
673  TRACE(m_CStates->size() << " models");
674  }
675  break;
676  case KEY_R: //R
677  {
678  vuLock glock(m_GeomMutex);
680 // for(vector<Model*>::iterator m=m_CStates->begin();
681 // m!=m_CStates->end(); m++) {
682 // (*m)->addNoise(0.05);
683 // (*m)->setWinner(false);
684 // }
685  }
686  break;
687  case KEY_K: //K
688  {
689  vuLock glock(m_GeomMutex);
690  killAllStates();
691  }
692  break;
693  case KEY_g: //g
694  {
696  loadModel(cs.getModel().getFilename().c_str()); //"shape.dm"
697  cs.setModel(*m_Geom);
698  }
699  break;
700  case KEY_G: //G
701  {
703  m_Geom->writeFile(cs.getModel().getFilename().c_str());
704  break;
705  }
706  case KEY_v: //v
707  {
708  vuLock glock(m_GeomMutex);
709  Node n((float)mx,(float)my);
710  bool doubleclick=false;
711  if(m_Geom->getNNodes()>0) {
712  Node &ln = m_Geom->getNode(m_Geom->getNNodes()-1);
713  doubleclick = ((n-ln).norm()<2);
714  }
715  if(doubleclick) {
716  //cout << "doubleclick"<<endl;
717  int lnid = m_Geom->getNNodes()-1;
718  if(lnid>0) {
719  m_Geom->addEdge(lnid-1,lnid);
721  }
722  } else {
725  }
726  }
727  break;
728  case KEY_V: //V
729  {
730  vuLock glock(m_GeomMutex);
732  }
733  break;
734  case KEY_u:
735  {
737  cout << m_DBSelector.getCurSpecies().getFlagString() << endl;
738  break;
739  }
740  case KEY_U:
741  {
742 // //one update step
743 // vuLock glock(m_GeomMutex);
744 // for(vector<Model*>::iterator m = m_CStates->begin();
745 // m!=m_CStates->end(); m++)
746 // {
747 // (*m)->updateParticles(m_TimeStep);
748 // }
750  cout << m_DBSelector.getCurSpecies().getFlagString() << endl;
751  break;
752  }
753  case KEY_1: //1
754  //m_Geom->pushRotate(m_Geom->getCenter(), 1);
755  m_Geom->rotate(M_PI*0.03);
756  break;
757  case KEY_2: //2
758  //m_Geom->pushRotate(m_Geom->getCenter(), -1);
759  m_Geom->rotate(-M_PI*0.03);
760  break;
761  case KEY_3:
762  if(m_Geom->getSelectedNodesN()) {
763  m_Geom->scaleSel(0.95, m_Geom->selMaskMat());
764  } else m_Geom->scale(0.95, true);
765  break;
766  case KEY_4:
767  if(m_Geom->getSelectedNodesN()) {
768  m_Geom->scaleSel(1.05, m_Geom->selMaskMat());
769  } else m_Geom->scale(1.05, true);
770  break;
771  case KEY_5: //5
772  if(m_Geom->getHLNode()>=0) {
773  m_Geom->getNode(m_Geom->getHLNode()).setPos(Point2D(mx,my));
774  for(int e=0; e<m_Geom->getNEdges(); e++) {
775  Edge& ed = m_Geom->getEdge(e);
776  if(ed.from == m_Geom->getHLNode() ||
777  ed.to == m_Geom->getHLNode()) ed.adaptRestLength();
778  }
779  }
780  break;
781  case KEY_6:
782  {
783  vuLock glock(m_GeomMutex);
785  m_Geom->getNode(m_Geom->getHLNode()).attachSensor(s);
786  break;
787  }
788  case KEY_7:
789  {
790  vuLock glock(m_GeomMutex);
791  sensor_ptr zs = std::make_shared<ZeroSensor>();
792  zs = m_Geom->getSensorCollection()->addSensor("zero", zs);
793  Node n; n.setPos(m_Geom->getNode(5));
794  //n.mass *= 0.1;
795  n.attachSensor(zs);
796  int nid = m_Geom->addNode(n);
797  int eid = m_Geom->addEdge(18, nid);
798  m_Geom->getEdge(eid).springconstant *= 1;
799  m_Geom->getEdge(eid).restlength *= 1.5;
800  m_Geom->getEdge(m_Geom->addEdge(4, nid)).springconstant *= 1;
801  m_Geom->getEdge(m_Geom->addEdge(6, nid)).springconstant *= 1;
803  break;
804  }
805  case KEY_8:
806  {
807  vuLock glock(m_GeomMutex);
809  (Searcher&)st.getSearcher() = m_Search;
810  break;
811  }
812  case KEY_9:
813  {
814  vuLock glock(m_GeomMutex);
816  m_Search = st.getSearcher();
817  break;
818  }
819  case KEY_F1: //F1
820  m_TimeScale*=2;
821  setStatusText(string("current time scale is ")
823  break;
824  case KEY_F2: //F2
825  m_TimeScale*=0.5;
826  setStatusText(string("current time scale is ")
828  break;
829  case KEY_F3: //F3
830  m_Done = !m_Done;
831  break;
832  case KEY_F4: //F4
833  {
834  vuLock glock(m_GeomMutex);
835 // determine range of qualities
836  float lqof,hqof;
837  getQualityRange(lqof,hqof,__SHAPEWEIGHT);
838 // remove bad ones
839  float kill_quality_th = 0.05;
840  float relq = (hqof-lqof)*kill_quality_th+lqof;
841  //(hqof!=0.0) ? (m->getQualityOfFit()-lqof)/hqof :1;
842  for(int mi=0; mi<(int)m_CStates->size()
843  && (int)m_CStates->size()>1;)
844  {
845  Model *m = (*m_CStates)[mi];
846  if(relq > m->getQualityOfFit()) {
847  //TRACE(relq);
848  killState(mi);
849  }else mi++;
850  }
851  break;
852  }
853  case KEY_P:
854  {
855  Point mouse(mx,my);
856  int mind=0; float md=1000000;
857  int cind = 0;
858  for(vector<Model*>::iterator m = m_CStates->begin();
859  m!=m_CStates->end(); m++,cind++)
860  {
861  float d = ((*m)->getCenter()-mouse).norm2();
862  if(!cind) md = d;
863  else if(d<md) {
864  md = d;
865  mind = cind;
866  }
867  }
868  vuLock glock(m_GeomMutex);
869  switchState(mind);
870  cout << "quality of fit "<<(m_Geom->getQualityOfFit()) << endl;
871  register float lv = m_Geom->getDeformation();
872  cout << "deformation: " << lv << " mapped: "<<exp(-5*abs(lv))<<endl;
873  cout << "sensors: "<< m_Geom->getSensorFit() << endl;
874  dword nes = 0;
875  cout << "edges: "<< m_Geom->getEdgeSensorFit(&nes) << endl;
876  cout << " nedgesensors: " << nes << endl;
877  cout << " flags: " << hex << m_Geom->getFlags() << endl;
878  break;
879  }
880  case KEY_0: //0
881  {
882  vuLock glock(m_GeomMutex);
883 // determine range of qualities (in terms of shape)
884  float lqof,hqof,aqof;
885  lqof=1;
886  hqof=0;
887  aqof=0;
888  for(vector<Model*>::const_iterator m = m_CStates->begin();
889  m!=m_CStates->end(); m++)
890  {
891  float lv = (*m)->getDeformation()*10;
892  lv = exp(-lv*lv);
893  if(lv>hqof) hqof=lv;
894  if(lv<lqof) lqof=lv;
895  aqof+=lv;
896  }
897  aqof /= m_CStates->size();
898 // remove bad ones
899  //float kill_quality_th = 0.03;
900  for(int mi=0; mi<(int)m_CStates->size()
901  && (int)m_CStates->size()>1;)
902  {
903  Model *m = (*m_CStates)[mi];
904  float lv = m->getDeformation()*10;
905  lv = exp(-lv*lv);
906  float relq = (hqof!=0.0) ? (lv-lqof)/hqof :1;
907  //if(relq < kill_quality_th && !m->isWinner()) {
908  if(lv < aqof && !m->isWinner()) {
909  TRACE(relq);
910  killState(mi);
911  }else mi++;
912  }
913  break;
914  }
915  case KEY_w: //w
916  {
917  list<const Model*> winners;
918  m_Search.getWinners( back_inserter( winners ) );
919  if(!winners.empty()) {
920  vuLock glock(m_GeomMutex);
921  m_CStates->clear();
922  for(list<const Model*>::iterator wpi = winners.begin();
923  wpi != winners.end(); wpi++)
924  duplicateState(*wpi);
925  switchState(0);
926  cout << "copied " << winners.size() << " winners" << endl;
927  }
928  break;
929  }
930  case KEY_t:
931  {
932  vuLock glock(m_GeomMutex);
933  dword nesensors = m_Geom->createEdgeSensors(0.15);
934  cout << "created " << nesensors << " edge sensors" << endl;
935  break;
936  }
937  case KEY_e:
938  { vuLock glock(m_GeomMutex); m_Geom->connectNodes(); break; }
939  case KEY_E:
940  { vuLock glock(m_GeomMutex); m_Geom->removeEdges(); break; }
941  case KEY_n:
942  {
943  for(int i = 0; i<m_Geom->getNNodes(); i++)
945  break;
946  }
947  case KEY_N:
948  {
949  for(int i = 0; i<m_Geom->getNNodes(); i++)
951  break;
952  }
953  case KEY_c:
954  {
955  vuLock glock(m_GeomMutex);
956  Node n((float)mx,(float)my);
957  bool doubleclick=false;
958  if(m_Geom->getNNodes()>0) {
959  Node &ln = m_Geom->getNode(m_Geom->getNNodes()-1);
960  doubleclick = ((n-ln).norm()<2);
961  }
962  if(doubleclick) {
963  //cout << "doubleclick"<<endl;
964  int lnid = m_Geom->getNNodes()-1;
965  if(lnid>0) {
966  m_Geom->addEdge(lnid-1,lnid);
968  }
969  } else {
972  }
973  break;
974  }
975 /*
976  case KEY_o: // postscript output
977  {
978  string fname = "graph.ps";
979  CAMgraphicsProcess Gprocess; // declare a graphics process
980  // declare a PostScript driver
981  CAMpostScriptDriver Pdriver(fname.c_str());
982  Gprocess.attachDriver(Pdriver); // Attach driver to process
983 
984  Gprocess.setAxisRange(0,m_BrowseData->getDim1Size(),0,
985  m_BrowseData->getDim2Size());
986  Gprocess.title("Deformable model"); // label the plot
987  Gprocess.labelX(" X ");
988  Gprocess.labelY(" Y ");
989  m_Geom->drawPS(Gprocess);
990  //Gprocess.plot(x,y,n); // do the plotting
991  Gprocess.frame(); // "frame" the plot
992 
993  Gprocess.detachDriver(); // detach the driver
994  cout << "wrote file " << fname << endl;
995  break;
996  }
997 */
998  case KEY_period: //.
1000 // *m_Prototypes[m_Geom->getName()] = *m_Geom;
1001  break;
1002  case KEY_Page_Up://pgup
1003  {
1006  break;
1007  }
1008  case KEY_Page_Down://pgdn
1009  {
1012  break;
1013  }
1014  case KEY_Home://home
1015  {
1016  m_DBSelector.nextSelector(-1, true, 4);
1018  break;
1019  }
1020  case KEY_End://end
1021  {
1022  m_DBSelector.nextSelector(1, true, 4);
1024  break;
1025  }
1026  case KEY_Insert:
1027  {
1028  cout << m_DBSelector.getCurSpecies();
1029  cout << "image resolution is " << m_BrowseData->getDim1Size()
1030  << ", " << m_BrowseData->getDim2Size() << endl;
1031  break;
1032  }
1033  case KEY_Escape:
1034  {
1035  cout << "current flags <"
1037  << "> change to (type 'savedb' to save DB): ";
1038  string cmdline;
1039  getline(cin, cmdline);
1040  dword split = cmdline.find(' ');
1041  string command = cmdline.substr(0,split);
1042  string value;
1043  if(split != cmdline.npos) value = cmdline.substr(split+1);
1044  cout << "command <" << command << "> value <"<<value<<">"<< endl;
1045  doCommand(command,value,mx,my);
1046  break;
1047  }
1048  case KEY_m:
1049  {
1050  vuLock glock((vuMutex&)m_GeomMutex);
1051 #if 0
1052 //scan through all reference models
1053  if(!m_SModel.getStructs().empty()) {
1054  list<dword> ids;
1056  cout << "scanning " << st.getName() << endl;
1057  cout << "nids: "
1058  << st.getRefModelIDs( back_inserter(ids) ) << endl;
1059  for(list<dword>::iterator mid = ids.begin();
1060  mid != ids.end(); mid++) {
1061  cout << *mid << endl;
1062  Dataset d;
1063  Model m(&d);
1064  if(st.getRefModel(*mid, m))
1065  cout << m.getProperties() << endl;
1066  }
1067  }
1068 #else
1070  if(*m_Geom) {
1071  cout << "setting reference model for species id "
1072  << m_CSpecies.id << endl;
1074  } else {
1075  cout << "setting reference frame for species id "
1076  << m_CSpecies.id << endl;
1077  PropVec frameprop(m_BrowseData->getPropVecMM());
1078  DUMP(frameprop);
1079  st.setRefProp(m_CSpecies.id, frameprop);
1080  }
1081 #endif
1082  break;
1083  }
1084  case KEY_M:
1085  {
1086  vuLock glock((vuMutex&)m_GeomMutex);
1088  if(st.getRefModel(m_CSpecies.id, *m_Geom)) {
1089  cout << "found reference model!" << endl;
1090 // list<Model*> ml;
1091 // if(getAllModels( back_inserter( ml ) )) {
1092 // for(list<Model*>::iterator gi=ml.begin();
1093 // gi != ml.end(); gi++)
1094 // (*gi)->reattachSensors();
1095 // }
1096 // m_Search.reattachSensors();
1097 // m_SModel.reattachSensors();
1099  PropVec prop;
1100  if(st.getRefProp(m_CSpecies.id, prop))
1101  DUMP(prop);
1102  } else cout << "could not find reference model" << endl;
1103  break;
1104  }
1105  case KEY_comma:
1106  {
1107  vuLock glock((vuMutex&)m_GeomMutex);
1109  if(cs) cout << "current structure is: " << cs.getName() << endl;
1110 // if(!cs.getRefModel(m_CSpecies.id, *m_Geom))
1111  *m_Geom = cs.getModel();
1113  break;
1114  }
1115  case KEY_slash:
1116  {
1117 //show next interpretation
1118  vuLock glock(m_GeomMutex);
1119  m_SModel.showNextIP();
1120  map<string,StructPath>::const_iterator cp =
1122  float qual = 0.f;
1123  if(cp != m_SModel.getIPaths().end())
1124  qual = cp->second.getRelGoodness();
1125  cout << "showing interpretation " << m_SModel.getShownIP()
1126  << " (" << qual << ")" << endl;
1127  break;
1128  }
1129  case KEY_backslash:
1130  {
1131 //show best interpretation
1132  vuLock glock(m_GeomMutex);
1133  m_SModel.setShownIP(string());
1134  cout << "switching to best interpretation" << endl;
1135  map<string,StructPath>::const_iterator cp =
1137  float qual = 0.f;
1138  if(cp != m_SModel.getIPaths().end())
1139  qual = cp->second.getRelGoodness();
1140  cout << "showing interpretation " << m_SModel.getShownIP()
1141  << " (" << qual << ")" << endl;
1142  break;
1143  }
1144  default:
1145  return false;
1146  }
1147  return true;
1148 }
1149 
1150 bool Brain::doCommand(const std::string& command, const std::string& value,
1151  int mx, int my)
1152 {
1153  if(command == "savedb") {
1154  ofstream os(m_DB.getFilename().c_str());
1155  if(os) {
1156  cout << "saving " << m_DB.getFilename();
1157  os << m_DB;
1158  os.close();
1159  cout << " done." << endl;
1160  } else cout << "Could not create " << m_DB.getFilename()<<endl;
1161  } else if(command == "scale0" || command == "scale1" ||
1162  command == "scaleh" || command == "scaled") {
1163  static int oldmx = -1;
1164  static float scale = 1;
1165  if(command == "scaleh") scale *= 0.5;
1166  else if(command == "scaled") scale *= 2;
1167  cout << "using scale " << scale << " mm" << endl;
1168  if(command == "scale0") oldmx = mx;
1169  else if(command == "scale1") {
1170  m_DBSelector.getCurSpecies()["scale"] =
1171  toString(abs(mx-oldmx)/scale);
1172  cout << m_DBSelector.getCurSpecies().getScale()
1173  << " pixels per mm" << endl;
1174  }
1175  } else if(command == "flags") {
1177  cout << endl << "new flags are <"
1179  << ">" << endl;
1180  } else if(command == "go") {
1181  dword id; fromString(value, id);
1182  //m_DB.select(Species(id));
1183  loadSpecies(m_DB[id]);
1184  } else if(command == "calstat") {
1186  st.buildAllStats();
1187  } else if(command == "selall") {
1189  cout << "selected all " << nsel
1190  << " species in data base" << endl;
1191  } else if(command == "process") {
1193  if(!*m_Geom) {
1196  dword firstid = 0;
1197  while(m_CSpecies.id != firstid) {
1198  if(!firstid) firstid = m_CSpecies.id;
1199  if(m_BrowseData->getPPMM()) {
1200  cout << "setting reference frame for species id "
1201  << m_CSpecies.id << endl;
1202  PropVec frameprop(m_BrowseData->getPropVecMM());
1203  DUMP(frameprop);
1204  st.setRefProp(m_CSpecies.id, frameprop);
1205  }
1208  }
1209  }
1210  } else if(command == "setdir") {
1211  if(value.empty()) {
1212  cout << "current dir node: "
1213  << m_Geom->getDirNode().getIndex() << endl;
1214  } else {
1215  int dirnode; fromString(value, dirnode);
1217  list<dword> refmod;
1218  st.getRefModelIDs( back_inserter(refmod) );
1219  cout << m_DB.select(refmod) << " species selected" << endl;
1220  Model model; // not attached to anything
1221  for(list<dword>::const_iterator idi = refmod.begin();
1222  idi != refmod.end(); idi++) {
1223  model.readFile(
1224  st.getInfoFilename(toString(*idi)).c_str());
1225  DUMP(model.getProperties());
1226  DUMP(model.getDirNode().getIndex());
1227  model.setDirNode(dirnode);
1228  DUMP(model.getProperties());
1229  DUMP(model.getDirNode().getIndex());
1230  st.setRefModel(*idi, model);
1231  }
1232  }
1233  } else if(command == "savesearcher") {
1234  string fname = value.empty() ? "searcher.cnf" : value;
1235  ofstream os(fname.c_str());
1236  getSearchPara().write(os, true);
1237  } else if(command == "hbs") {
1238  dword hbs; fromString(value, hbs);
1239  m_BrowseData->setHalveBeyondSize(hbs);
1240  cout << "image resolution is halved beyond a size of "
1241  << m_BrowseData->getHalveBeyondSize() << endl;
1242  } else if(command == "analysis") {
1243  intptr_t para=0; fromString(value, para);
1244  startThread(DO_ANALYSIS, (void*)para);
1245  } else if(command == "noise") {
1246  cout << "going for noise" << endl;
1247  float para=255.f; fromString(value, para);
1248  m_BrowseData->addNoise(para);
1249  } else {
1250  cout << "command not recognized" << endl;
1251  return false;
1252  }
1253  return true;
1254 }
1256  if(state < m_CStates->size()) {
1257  m_CurState = state;
1258  m_Geom = (*m_CStates)[state];
1259  return true;
1260  }else {
1261  m_CurState = 0;
1262  m_Geom = (*m_CStates)[0];
1263  return false;
1264  }
1265 }
1266 
1268  if(!model) model = m_Geom;
1269  m_Geom = new Model(*model);
1270  m_CStates->push_back(m_Geom);
1271  m_CurState = m_CStates->size()-1;
1272  return m_CurState;
1273 /*
1274  m_CStates->push_back(new Model(*m_Geom));
1275  return m_CStates->size()-1;
1276  TRACE(m_CurState);
1277 */
1278 }
1279 
1281  if(state>=m_CStates->size()) return;
1282  if(m_CStates->size() == 1) return;
1283  else {
1284  delete (*m_CStates)[state];
1285  m_CStates->erase(m_CStates->begin()+state);
1286  }
1287  if(state<=m_CurState) m_CurState--;
1289 }
1290 
1292  //done in sub-procedure vuLock glock(m_GeomMutex);
1293  while(m_CStates->size()>1) {
1294  if(m_CurState==0) killState(1);
1295  else killState(0);
1296  }
1297 }
1298 
1299 int Brain::distributeModel(const Model &model, int n, float qth, bool count)
1300 {
1301  int cstate = m_CurState;
1302  int i;
1303  int cs=0;
1304  int dist = (int)model.getStdRadius()+1;
1305  int sx = m_Data->getDim1Size()/dist;
1306  int sy = m_Data->getDim2Size()/dist;
1307  if(n==0) { // jittering
1308  int j;
1309  for(j=0; j<m_Data->getDim2Size(); j+=dist)
1310  for(i=0; i<m_Data->getDim1Size(); i+=dist)
1311  {
1312  duplicateState(&model);
1313  Point p(i,j);
1314  p += Point(frand(dist), frand(dist)); // jittering
1316  m_Geom->rotate(frand(2*M_PI));
1317  m_Geom->scale(max(fgauss01()*0.3f+1.f, 0.1f),true);
1319  if(m_Geom->getQualityOfFit() < qth) {
1320  killCurrentState();
1321  } else cs++;
1322  }
1323  } else { // monte carlo
1324  if(n<0)
1325  n = (int)(m_Data->getDim1Size()*m_Data->getDim2Size()/(dist*dist));
1326  for(i=0; i<n; i++) {
1327  duplicateState(&model);
1328  Point p(frand(m_Data->getDim1Size()), // monte carlo
1329  frand(m_Data->getDim2Size()));
1330  m_Geom->translate(p-m_Geom->getCenter()); //random position
1331  m_Geom->rotate(frand(2*M_PI)); //rand. orient.
1332  m_Geom->scale(max(fgauss01()*0.3f+1.f, 0.1f),true);
1334  if(m_Geom->getQualityOfFit() < qth) {
1335  killCurrentState();
1336  if(count) i--;
1337  } else cs++;
1338  }
1339  }
1340  switchState(cstate);
1341  return cs;
1342 }
1343 
1344 void Brain::drawAllModels() const {
1345  vuLock glock((vuMutex&)m_GeomMutex);
1346  vuLock dlock((vuMutex&)m_DataMutex);
1347 //draw winners
1348  m_Search.draw();
1349  m_SModel.draw();
1350  if(m_DrawOwnState) {
1351  if(m_CStates->empty()) return;
1352  float lqof,hqof;
1353  getQualityRange(lqof,hqof);
1354  if(lqof>0) lqof=0;
1355  //TRACE("qmin="<<lqof<<" qmax="<<hqof);
1356  if(!m_DesignMode) {
1357 //draw instances
1358  glLineWidth(1.0f);
1359  for(vector<Model*>::const_iterator m = m_CStates->begin();
1360  m!=m_CStates->end(); m++)
1361  {
1362  if(m_Geom != *m) {
1363  float alpha = (hqof!=0.0) ? ((*m)->getQualityOfFit()-lqof)/hqof :0;
1364  alpha = alpha*0.8+0.2;
1365  glColor4f(0.1,0.2,0.9,alpha);
1366  (*m)->draw();
1367  }
1368  }
1369 
1370  } else { // is design mode
1371  glColor3f(1,1,0);
1372  sglBitmapString("design mode",10,20);
1373  }
1374 
1375 //draw selected one
1376  float alpha=0.0;
1377  if(hqof!=0.0)
1378  alpha = (m_Geom->getQualityOfFit()-lqof)/hqof;
1379  alpha = alpha*0.6+0.4;
1380  glEnable(GL_LINE_SMOOTH); // looks nice but BIG performace killer
1381  //glColor4f(0.0f, 0.0f, 1.0f,alpha);
1382  glColor4f(0.0f, 0.0f, 0.0f,alpha);
1383  glLineWidth(5.0f);
1385  glLineWidth(3.0f);
1386  glColor4f(1.0f, 1.0f, 1.0f,alpha);
1388  glDisable(GL_LINE_SMOOTH); // looks nice but BIG performace killer
1389  //cout << (m_Geom->getQualityOfFit()) << endl;
1390 
1391 //draw names
1392 #ifdef _DRAW_MODEL_NAMES_
1393  for(vector<Model*>::const_iterator m = m_CStates->begin();
1394  m!=m_CStates->end(); m++)
1395  {
1396  if((*m)->isWinner() || (*m) == m_Geom ) {
1397  Point c = (*m)->getCenter();
1398  stringstream descr;
1399  descr << (*m)->getName();// << " " << (*m)->getLiveliness();
1400  sglBitmapStringOutlined(descr.str().c_str(),(int)c.x,(int)c.y);
1401  }
1402  }
1403 #endif
1404  } // of draw own state
1405  {
1406  glLineWidth(1.0f);
1407  glColor3f(1,1,1);
1408  map<string,StructPath>::const_iterator spath =
1410  if(spath != m_SModel.getIPaths().end()) {
1411  stringstream descr;
1412  descr << m_SModel.getShownIP() << " ";
1413  descr << spath->second.getRelGoodness();
1414  sglBitmapString(descr.str().c_str(),10,m_Data->getDim2Size()-20);
1415  }
1416 // sglBitmapString(m_CurPrototype.c_str(),10,m_Data->getDim2Size()-20);
1417  }
1418  if(m_Data->getFilename() != m_BrowseData->getFilename()) {
1419  glColor3f(1,1,0);
1420  sglBitmapString("SENSORS NOT ATTACHED!",10,40);
1421  }
1422 }
1423 
1424 void Brain::evolve(float dt)
1425 {
1426  if(m_Done || !m_Data->initialized()) return;
1427 
1428  static float t=0;
1429  t+=dt;
1430 
1431  m_SModel.stepSearch(dt);
1432 
1433  static float search_evolve_t = 0;
1434  if(t-search_evolve_t > getSearchPara().m_EvolveCycle) {
1435  m_Search.evolve();
1436  search_evolve_t = t;
1437  }
1438  m_Search.step(dt);
1439 
1440  return;
1441 
1442 // determine range of qualities
1443  float lqof,hqof;
1444  getQualityRange(lqof,hqof);
1445  //if(lqof>0) lqof=0;
1446 
1447 //remove bad ones
1448  static float kill_t = 0;
1449  if(t-kill_t > 6) {
1450  float kill_quality_th = 0.1;
1451  for(int mi=0; mi<(int)m_CStates->size()
1452  && (int)m_CStates->size()>1;)
1453  {
1454  Model *m = (*m_CStates)[mi];
1455  float relq = (hqof!=0.0) ? (m->getQualityOfFit()-lqof)/hqof :1;
1456  if(relq < kill_quality_th) {
1457  //TRACE(relq);
1458  killState(mi);
1459  }else mi++;
1460  }
1461  kill_t = t;
1462  }
1463 
1464 //create some (not used yet)
1465  //TRACE("min "<<lqof<<" max "<<hqof);
1466  if(0 && hqof-lqof < 0.001 && m_Geom->getNNodes()>0) {
1467  static bool duplicated=false;
1468  if(duplicated && hqof-lqof>0) m_Done = true;
1469  else {
1470  duplicated = true;
1471  int cstate = m_CurState;
1472  int dist = (int)(1.5*m_Geom->getStdRadius());
1473  int i,j;
1474  for(j=dist/2;j<m_Data->getDim2Size(); j+=dist)
1475  for(i=dist/2;i<m_Data->getDim1Size(); i+=dist) {
1476  duplicateState();
1478  }
1479  switchState(cstate);
1480  }
1481  }
1482 
1483 //randomize bad ones
1484  static float laze_t = 0;
1485  //static bool lazing = true;
1486  static float change_t = 0;
1487  if(t-change_t > 0.2)
1488  {
1489  if(t-laze_t < 1) {
1490  float change_quality_th = 0.7;
1491  for(vector<Model*>::iterator m=m_CStates->begin();
1492  m!=m_CStates->end();m++)
1493  {
1494  float relq = (hqof!=0.0) ? ((*m)->getQualityOfFit()-lqof)/hqof :1;
1495  //TRACE((*m)->getLiveliness());
1496  if(relq < change_quality_th && (*m)->getLiveliness()<1) {
1497  (*m)->pushRotate((*m)->getCenter(), -1+frand(2));
1498  (*m)->addNoise(0.05);
1499  }
1500  }
1501  } else if(t-laze_t > 3) laze_t = t;
1502  change_t = t;
1503  }
1504 }
1505 
1506 void Brain::getQualityRange(float &lqof, float &hqof, float shapeweight) const
1507 {
1508  bool cw = (shapeweight!=-1);
1509  if(cw) (*m_CStates->begin())->setShapeWeight(shapeweight);
1510  lqof=hqof=(*m_CStates->begin())->getQualityOfFit();
1511  for(vector<Model*>::const_iterator m = m_CStates->begin();
1512  m!=m_CStates->end(); m++)
1513  {
1514  if(cw)(*m)->setShapeWeight(shapeweight);
1515  if((*m)->getQualityOfFit()>hqof) hqof=(*m)->getQualityOfFit();
1516  if((*m)->getQualityOfFit()<lqof) lqof=(*m)->getQualityOfFit();
1517  }
1518 }
1519 
1520 void Brain::setupSearch(enum SearchWhat what, const PropVec& prop)
1521 {
1523  //ExpectationMap::EDistList& cdl=cem.getDistList();
1524  if(what == SW_SET && cem) {
1525  cem.setRepresentative(*m_Geom);
1526  } else {
1527  ExpectationMap em(*m_Geom);
1528  PropVec propl(0.), propu(0.);
1529  if(what != SW_RESET && cem) {
1530  propu = cem.getUB();
1531  propl = cem.getLB();
1532  } else {
1533  Point2D dims((float)m_Data->getDim1Size(),
1534  (float)m_Data->getDim2Size());
1535  float scale = m_Geom->getStdRadius();
1536  setPropPos(propu, dims);
1537  setPropDir(propu, 2*M_PI);
1538  setPropScale(propu, scale*2);
1539  setPropScale(propl, scale*0.5);
1540  }
1541  if(what == SW_UB) propu = prop;
1542  else if(what == SW_LB) propl = prop;
1543  else if(what == SW_SPREAD) {
1544  float radius = getPropScale(prop);
1545  PropVec plusminus;
1546  setPropPos(plusminus, Point2D(radius, radius));
1547  setPropScale(plusminus, getPropScale(prop)*0.2);
1548  setPropDir(plusminus, M_PI*0.2);
1549  propu = prop+plusminus;
1550  propl = prop-plusminus;
1551  }
1552  ExpectationMap::correctLBUB(propl, propu);
1553  em.setLB(propl);
1554  em.setUB(propu);
1555  em.add(new EMDRect(propl,propu));
1557  }
1560 }
bool loadData(const char *filename, dword ppmm=0)
Definition: Brain.cpp:288
const std::map< std::string, StructPath > & getIPaths() const
Definition: StructTable.h:93
#define EXIT_THREAD(t)
Definition: Brain.cpp:318
float imgforce
Definition: PartParam.h:67
ExpectationMap & getExpectationMap()
Definition: Searcher.h:37
std::string getInfoFilename(const std::string &suffix) const
Definition: MStruct.cpp:157
bool changeModel(const std::string &mname)
Definition: Brain.cpp:231
#define NULL
Definition: simpletypes.h:9
void startSearch(bool dostart=true)
#define DUMP(expr)
Definition: common.h:16
dword readFlagString(const std::string &flags)
Definition: SpeciesDB.cpp:189
void setExpectationMap(const ExpectationMap &em)
Definition: Searcher.cpp:346
bool writeFile(const char *filename) const
Definition: Model.cpp:381
float getQualityOfFit() const
Definition: Model.cpp:1204
void prepareTorque()
Definition: Model.cpp:713
std::string m_CurPrototype
Definition: Brain.h:96
bool load(const char *bfile)
Definition: Brain.cpp:87
int getNEdges() const
Definition: Model.h:78
void attachSensor(sensor_cptr _sensor)
Definition: Node.cpp:50
void rotate(float angle, const Point &c)
Definition: Model.cpp:946
T & fromString(const std::string &str, T &v)
Definition: utils.h:67
SpeciesDB m_DB
Definition: Brain.h:98
Implements a Node used by Model and Edge.
Definition: Node.h:13
void buildAllStats()
Definition: MStruct.cpp:232
float getEdgeSensorFit(dword *npts=NULL) const
get average fit of sensors along edges
Definition: Model.cpp:1191
#define frand(max)
Definition: mathutil.h:48
int getHLNode() const
Returns ID of highlighted node. Value is -1 if none is selected.
Definition: Model.h:231
const std::string & getShownIP() const
Definition: StructTable.h:97
std::map< std::string, MStructure > & getStructs()
Definition: StructTable.h:71
const PropVec & getProperties() const
Definition: Model.cpp:1263
float getStdRadius(const Point &center) const
Returns mean squared distance from centroid.
Definition: Model.cpp:1018
bool triggerTest(int mx, int my, int what=0)
Definition: Brain.cpp:442
void evalRelations()
bool loadModel(const char *filename)
Definition: Brain.cpp:163
DBSelector m_DBSelector
Definition: Brain.h:99
bool triggerTest(int mx, int my, int what)
Definition: Searcher.cpp:728
void setDirNode(int id)
Definition: Model.h:177
bool triggerTest(int mx, int my, int what)
float adaptRestLength()
Definition: Edge.h:95
~Brain()
Definition: Brain.cpp:46
void setHLNode(int hlnode)
Definition: Model.cpp:405
bool loadSpecies(const Species &spec)
Definition: Brain.cpp:210
void drawAllModels() const
Definition: Brain.cpp:1344
const Model & getRepresentative() const
Definition: Searcher.h:43
void adaptProportion(float ratio)
overall rest lengths sum is adapted to overall edge lengths by ratio
Definition: Model.cpp:1164
bool nextSelector(int walkdir=1, bool wrap=true, dword mincount=1)
Definition: SpeciesDB.cpp:291
float y
Definition: Point.h:224
void setShapeWeight(float weight)
Definition: Model.h:201
const Node & getDirNode() const
Definition: Model.cpp:870
void updateModels() const
Definition: SensorColl.cpp:292
bool mergeInstances()
Definition: Brain.cpp:261
#define TRACE(msg)
Definition: common.h:14
dword id
Definition: SpeciesDB.h:41
dword duplicateState(const Model *model=NULL)
Definition: Brain.cpp:1267
dword createEdgeSensors(float dist=0.1)
auto-create appropriate edge sensors (dist*stdRadius is distance)
Definition: Model.cpp:622
STL namespace.
std::string toString(T v)
Definition: utils.h:60
const std::string & getDirectory() const
Definition: SpeciesDB.h:55
static void correctLBUB(PropVec &lb, PropVec &ub)
Definition: ExpMap.cpp:193
Model * m_Geom
Definition: Brain.h:92
int getIndex() const
Definition: Node.h:33
unsigned long getMilliSeconds()
Definition: utils.h:41
int searchDone() const
Definition: StructTable.h:81
void attachBrowseData()
Definition: Brain.cpp:300
const std::string & getSelectedSensor() const
Definition: SensorColl.h:32
Implements an Edge with spring functionality.
Definition: Edge.h:14
ParticleParam phys
physical parameter set
Definition: Model.h:257
float getPropScale(const PropVec &prop)
Definition: PropVec.h:19
bool hasFlag(dword flag) const
Definition: SpeciesDB.cpp:169
bool switchState(dword newstate)
Definition: Brain.cpp:1255
Species m_CSpecies
Definition: Brain.h:100
bool startThread(int whatsup, void *data=NULL)
Definition: vuThread.cpp:45
bool doCommand(const std::string &command, const std::string &value, int mx=0, int my=0)
Definition: Brain.cpp:1150
std::shared_ptr< Sensor > sensor_ptr
Definition: types_fwd.h:15
void disableState(dword nstate=0xffffffff)
Definition: Node.h:39
void setShownIP(const std::string &curip) const
Definition: StructTable.h:95
void scale(float factor, bool movepoints=false)
multiply all rest lengths by factor
Definition: Model.cpp:1140
int sglBitmapString(const char *msg, int x, int y, void *font=(void *) GLUT_BITMAP_8_BY_13)
Definition: glutils.h:7
bool m_UpdateAllModels
Definition: Brain.h:103
dword connectNodes()
Connect selected nodes.
Definition: Model.cpp:483
void add(EMDistribution *ed)
Definition: ExpMap.cpp:23
int nearestNode(const Point &pos, float &dist=*(float *)(NULL)) const
Definition: Model.cpp:1108
void adaptRestLength(float ratio)
adapt restlengths towards current lengths by ratio
Definition: Model.cpp:1126
bool read(ParseFile &is)
Definition: Searcher.cpp:924
sensor_ptr getSensor(const std::string &id)
Definition: SensorColl.cpp:52
Node & setPos(const Point &p)
Definition: Node.h:28
const std::string & getValue() const
Definition: ParseFile.h:57
void killAllStates()
Definition: Brain.cpp:1291
Brain()
Definition: Brain.cpp:27
void evolve()
Definition: Searcher.cpp:163
Point2D Point
Definition: Point.h:251
dword getRefModelIDs(Iter iter) const
Definition: MStruct.h:131
dword & getFlags()
Definition: Model.h:196
void setupSearch(enum SearchWhat what=SW_RESET, const PropVec &prop=PropVec())
Definition: Brain.cpp:1520
bool stepSearch(float dt)
const Point getCenter() const
Definition: Model.cpp:852
bool loadDBSelector(const char *filename)
Definition: Brain.cpp:203
float getSensorFit(dword *npts=NULL) const
get average sensor value
Definition: Model.cpp:1173
std::ostream & write(std::ostream &os, bool showcomment=false) const
Definition: Searcher.cpp:832
bool getRefModel(dword id, Model &model) const
Definition: MStruct.cpp:167
PropVec & setPropDir(PropVec &prop, float dir)
Definition: PropVec.h:28
bool setTitle(const char *title)
Definition: browser.cpp:154
const Searcher & getSearcher() const
Definition: MStruct.h:73
bool m_Done
Definition: Brain.h:106
bool getRefProp(dword id, PropVec &prop) const
Definition: MStruct.cpp:174
void reattachSensors()
get sensors from sensor collection
Definition: Model.cpp:616
bool load(const std::string &filename)
Definition: StructTable.cpp:69
bool load(const char *filename)
Definition: SpeciesDB.cpp:241
bool showNextIP(int dir=1) const
const Model & getModel() const
Definition: MStruct.h:67
std::map< std::string, Model * > m_Prototypes
Definition: Brain.h:94
int getNNodes() const
Definition: Model.h:77
const std::string & getFilename() const
Definition: StructTable.h:69
bool step(float dt)
Definition: Searcher.cpp:288
PropVec & setPropPos(PropVec &prop, const Point2D &p)
Definition: PropVec.h:16
float springconstant
spring constant
Definition: Edge.h:134
dword setFlag(dword flag)
Definition: SpeciesDB.cpp:173
void evolve(float dt)
Definition: Brain.cpp:1424
void setUB(const PropVec &ub)
Definition: ExpMap.h:87
const std::string & getFilename() const
Definition: SpeciesDB.h:56
void toggleUpdateForAll(bool onoff=true)
Definition: Brain.h:64
const Dataset & getData() const
Definition: Brain.cpp:77
void draw() const
Definition: Searcher.cpp:687
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 std::string & getBestInterpretation() const
Definition: StructTable.h:92
DMatrix< T > & abs(DMatrix< T > &mat)
Definition: DMatrixUtil.h:132
Definition: ExpMap.h:73
dword removeEdges()
Remove edges between selected nodes.
Definition: Model.cpp:498
int addNode(const Node &node)
Definition: Model.cpp:120
const Node & getNode(int index) const
Definition: Model.h:74
#define M_PI
Definition: mathutil.h:9
#define MERGENAME
Definition: Brain.cpp:23
Searcher m_Search
Definition: Brain.h:110
Definition: Model.h:33
dword m_CurState
Definition: Brain.h:97
int from
Definition: Edge.h:128
const PropVec & getLB() const
Definition: ExpMap.h:86
bool m_ImmediateData
Definition: Brain.h:108
dword getSelectedNodesN(dword state=Node::ST_SELECT) const
get number of selected nodes
Definition: Model.cpp:1334
SearcherParams & getSearchPara()
Definition: Searcher.h:194
int to
Definition: Edge.h:128
void setRefProp(dword id, const PropVec &prop)
Definition: MStruct.cpp:183
bool m_ThreadActive[DO_LAST]
Definition: Brain.h:105
void setModel(const Model &model)
Definition: MStruct.h:66
unsigned long dword
Definition: simpletypes.h:6
void adaptRestLengthSel(float ratio, const DMatrixf &selm)
adapt restlengths of selected edges towards current lengths by ratio
Definition: Model.cpp:1133
dataset_ptr m_Data
Definition: Brain.h:89
SensorCollection * getSensorCollection()
Definition: Model.h:168
void translate(const Point &t)
Definition: Model.cpp:923
const std::string & getName() const
Definition: MStruct.h:63
void killState(dword state)
Definition: Brain.cpp:1280
float fgauss01()
Definition: mathutil.h:53
float m_TimeStep
Definition: Brain.h:101
void setRefModel(dword id, const Model &model)
Definition: MStruct.cpp:188
unsigned long nowticks
Definition: analysis.cpp:27
bool m_DrawOwnState
Definition: Brain.h:109
Definition: Data.h:21
void draw(bool drawPoints=false) const
Draw using OpenGL.
Definition: Model.cpp:542
dword getAllModels(Iter iter)
Definition: Brain.h:116
const Edge & getEdge(int index) const
Definition: Model.h:71
vuMutex m_GeomMutex
Definition: Brain.h:104
int addEdge(const Edge &edge)
Definition: Model.cpp:138
void removeNode(int nid)
Removes a node and its adjacent edges.
Definition: Model.cpp:508
#define CHECK_THREAD(t)
Definition: Brain.cpp:324
void adaptDataScale()
Definition: StructTable.cpp:60
dword getScale() const
Definition: SpeciesDB.cpp:229
float restlength
Definition: Edge.h:132
vuMutex m_DataMutex
Definition: Brain.h:104
StructTable m_SModel
Definition: Brain.h:112
int distributeModel(const Model &model, int n=-1, float qth=0, bool count=false)
Definition: Brain.cpp:1299
const PropVec & getUB() const
Definition: ExpMap.h:85
const std::string & getFilename() const
Definition: Model.h:225
void unlock()
Definition: vuThread.cpp:148
void setParseError(const std::string &msg="")
Definition: ParseFile.h:80
dataset_ptr m_BrowseData
Definition: Brain.h:90
int sglBitmapStringOutlined(const char *msg, int x, int y, void *font=(void *) GLUT_BITMAP_8_BY_13)
Definition: glutils.h:22
void getQualityRange(float &lqof, float &hqof, float shapeweight=-1) const
Definition: Brain.cpp:1506
dword select(const Species &rhs, enum Species::SpCompare how=Species::CMP_CONTAINS)
Definition: SpeciesDB.cpp:37
unsigned int getWinners(Iter iter) const
Definition: Searcher.h:90
std::string getFlagString() const
Definition: SpeciesDB.cpp:181
Dataset & getSensorData()
Definition: Brain.cpp:82
#define __SHAPEWEIGHT
Definition: Brain.cpp:22
std::string getErrorMsg() const
Definition: ParseFile.h:85
SensorCollection m_Sensors
Definition: Brain.h:91
bool readFile(const char *filename, bool fullread=true)
Definition: Model.cpp:365
dword unsetFlag(dword flag)
Definition: SpeciesDB.cpp:177
std::vector< Model * > * m_CStates
Definition: Brain.h:93
bool nextSelection(int dir=1, bool wrap=true)
Definition: SpeciesDB.cpp:261
Definition: Point.h:16
DMatrixf selMaskMat() const
compute mask matrix of selected nodes
Definition: Model.cpp:431
void scaleSel(float factor, const DMatrixf &selm)
multiply all rest lengths of selected edges by factor
Definition: Model.cpp:1156
bool m_DesignMode
Definition: Brain.h:107
const std::string & getName() const
Definition: Model.h:81
float m_TimeScale
Definition: Brain.h:102
PropVec & setPropScale(PropVec &prop, float pscale)
Definition: PropVec.h:22
void killCurrentState()
Definition: Brain.h:63
MStructure & getNextStruct(int dir=1, bool wrap=true)
Species & getCurSpecies()
Returns a handle to the currently selected species in the data base.
Definition: SpeciesDB.h:90
#define TIMESTEP
Definition: Brain.h:25
vuMutex m_RunMutex[DO_LAST]
Definition: Brain.h:104
void addNoise(float r)
Definition: Model.cpp:901
std::map< std::string, std::vector< Model * > > m_Instances
Definition: Brain.h:95
float getDeformation() const
normalized length variation to compensate for different sizes
Definition: Model.cpp:995
void run(int whatsup, void *data)
virtual from vuThread
Definition: Brain.cpp:334
bool setStatusText(const char *stext)
Definition: browser.cpp:164
float x
Definition: Point.h:224
bool loadDB(const char *filename)
Definition: Brain.cpp:195
static void usleep(unsigned long ms)
sleep for n microseconds (!!not yet implemented for win32)
Definition: vuThread.cpp:112
void lock()
Definition: vuThread.cpp:138
void enableState(dword nstate)
Definition: Node.h:38
const bool getNextLine()
Definition: ParseFile.h:59
void setLB(const PropVec &lb)
Definition: ExpMap.h:88
void draw() const
sensor_ptr addSensor(const std::string &key, sensor_ptr s)
Definition: SensorColl.cpp:24
void setRepresentative(const Model &model)
Definition: ExpMap.cpp:18
void reset()
Definition: SpeciesDB.cpp:163
SearchWhat
Definition: Brain.h:85
void update()
should be called when data base has changed
Definition: SpeciesDB.cpp:255