evodataviewer.cpp
1 /********************************************************************************
2  * FARSA Experiments Library *
3  * Copyright (C) 2007-2012 *
4  * Stefano Nolfi <stefano.nolfi@istc.cnr.it> *
5  * Onofrio Gigliotta <onofrio.gigliotta@istc.cnr.it> *
6  * Gianluca Massera <emmegian@yahoo.it> *
7  * Tomassino Ferrauto <tomassino.ferrauto@istc.cnr.it> *
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  * This program is distributed in the hope that it will be useful, *
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17  * GNU General Public License for more details. *
18  * *
19  * You should have received a copy of the GNU General Public License *
20  * along with this program; if not, write to the Free Software *
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
22  ********************************************************************************/
23 
24 #include "evodataviewer.h"
25 
26 #include <QPainter>
27 #include <QPen>
28 #include <QPaintEvent>
29 #include <QApplication>
30 #include <QScrollArea>
31 #include <QDebug>
32 #include <QStringList>
33 #include <QtGui>
34 #include <QtAlgorithms>
35 #include <configurationparameters.h>
36 #include "logger.h"
37 
38 namespace farsa {
39 
41 EvoDataViewer::EvoDataViewer(int nchunks, int chunksize, int style, QWidget* parent, Qt::WindowFlags flags) :
42  QWidget(parent,flags)
43 {
44  //to do: put this stuff within a method
45  this->style=style;
46  panning_width=4;
47  label_width=100;
48  this->setMaximumWidth(chunksize+label_width);
49  this->setMinimumWidth(label_width*2);
50  this->setMinimumHeight(10*nchunks);
51  this->nviewChange=false;
52  vchunks=new int[nchunks];
53 
54  this->setAttribute(Qt::WA_OpaquePaintEvent, true);
55 
56  qpixmap = new QPixmap(width(), height());
57 
58  //initialiazing datachunks
59  this->nchunks = nchunks;
60  this->chunksize = chunksize;
61  this->nvchunks=nchunks;
62 
63  dataChunks = new DataChunk*[nchunks];
64  for(int i=0;i<nchunks;i++) {
65  dataChunks[i] = new DataChunk(QString("chunk"),QColor(255,0,0),chunksize, true);
66  }
67 
68  stepChunk=new DataChunk(QString("step"),QColor(255,0,0),chunksize, false);
69 
70  //this->setChunkLabel(0,"Input");
71 
72  this->listVisibleChunks();
73 
74  qtimer=new QTimer(this);
75  qtimer->setInterval(4000);
76  QObject::connect(qtimer,SIGNAL(timeout()),this,SLOT(pickUnvisible()));
77 
78  elw=NULL;
79 
80 
81  pickY = 0;
82  pickX = 0;
83  pickValueVisible = false;
84 
85 }
86 EvoDataViewer::~EvoDataViewer()
87 {
88  for(int i=0;i<nchunks;i++) {
89  delete dataChunks[i];
90  }
91  delete[] dataChunks;
92 
93  delete stepChunk;
94 
95  delete qpixmap;
96  delete elw;
97 }
98 
100 void EvoDataViewer::evoDataPaint()
101 {
102  //draws background and labels and axes
103  QPainter painter(qpixmap);
104  QPen pen(Qt::black, 1);
105  QPen pen2(Qt::lightGray);
106  QPen pen3(Qt::darkGray);
107  painter.setPen(pen);
108  int hh;
109 
110  painter.fillRect(0,0,width(),height(),Qt::white);
111 
112  for(int i=0;i<nvchunks+1;i++)
113  {
114 
115  painter.setPen(pen);
116  if (i<nvchunks)
117  {
118  painter.drawText(4,(int)(vertical_step*(i+1)-vertical_step/2.0),dataChunks[vchunks[i]]->getLabel());
119  painter.drawText(label_width-40,(int)(vertical_step*(i+1))-4,QString::number(dataChunks[vchunks[i]]->getRangeMin()));
120  painter.drawText(label_width-40,(int)(vertical_step*(i+1))-4-(int)(vertical_step-20),QString::number(dataChunks[vchunks[i]]->getRangeMax()));
121  }
122  //drawing range
123 
124  painter.drawLine(0,(int)(vertical_step*i),width(),(int)(vertical_step*i));
125 
126  painter.setPen(pen3);
127  painter.drawLine(0,(int)(vertical_step*i+1),width(),(int)(vertical_step*i+1));
128 
129  painter.setPen(pen2);
130  painter.drawLine(0,(int)(vertical_step*i+2),width(),(int)(vertical_step*i+2));
131  // painter.drawLine(50,50,400,400);
132  //painter.drawText(4,(int)(vertical_step*i),dataChunks[i]->
133 
134  }
135 
136  hh=(int)(vertical_step*(nvchunks));
137  painter.setPen(pen);
138 
139  painter.drawLine(label_width-1,0,label_width-1,hh);
140  painter.setPen(pen2);
141 
142  painter.drawLine(label_width,0,label_width,hh);
143  painter.drawLine(label_width-2,0,label_width-2,hh);
144 }
145 
147 void EvoDataViewer::updateGraphic(int ch)
148 {
149  if (nviewChange) {
150  reset();
151  nviewChange = false;
152  }
153 
154  if (!dataChunks[ch]->isVisible()) {
155  // If the chunk is not visible, we have nothing to do
156  return;
157  }
158 
159  QPainter painter(qpixmap);
160  const QPen pen(Qt::red);
161  const QPen penw(Qt::white);
162  const QPen leadpen(Qt::black);
163 
164  // Computing the index of the chunk excluding invisible ones
165  int i = 0;
166  for (int ii = 0; ii < ch; ii++) {
167  if (dataChunks[ii]->isVisible()) {
168  i++;
169  }
170  }
171 
172  int actualindex = -1;
173  int predindex;
174 
175  if(dataChunks[i]->getIndex() > -1) {
176  actualindex=(int)(dataChunks[vchunks[i]]->getIndex()*dataChunks[vchunks[i]]->getDPRatio());
177  predindex=(int)((dataChunks[vchunks[i]]->getIndex()-1)*dataChunks[vchunks[i]]->getDPRatio());
178  painter.setPen(pen);
179 
180  QPen personalpen(dataChunks[vchunks[i]]->getColor());
181  painter.setPen(personalpen);
182 
184  int zeropoint=(int)((vertical_step-panning_width-1)*dataChunks[vchunks[i]]->getZeroValue());
185 
186  if (style == 0) {
187  painter.drawLine(actualindex+label_width,(int)(vertical_step*(i+1)-1)-zeropoint,actualindex+label_width,(int)(vertical_step*(i+1)-1)-zeropoint-(int)((dataChunks[vchunks[i]]->getValueToDraw()-dataChunks[vchunks[i]]->getZeroValue())*(vertical_step-panning_width)));
188  } else if (style == 1) {
189  painter.drawLine(actualindex+label_width,(int)(vertical_step*(i+1)-1)-zeropoint-(int)((dataChunks[vchunks[i]]->getValueToDraw()-dataChunks[vchunks[i]]->getZeroValue())*(vertical_step-panning_width)),predindex+label_width,(int)(vertical_step*(i+1)-1)-zeropoint-(int)((dataChunks[vchunks[i]]->getValue(dataChunks[vchunks[i]]->getIndex()-1)-dataChunks[vchunks[i]]->getZeroValue())*(vertical_step-panning_width)));
190  }
191 
192  }
193 
194  //white line
195  painter.setPen(penw);
196  painter.drawLine(actualindex+label_width+1,(int)(vertical_step*(i+1)-1),actualindex+label_width+1,(int)(vertical_step*(i+1)-1)-(int)(vertical_step-panning_width));
197 
198  //lead line
199  painter.setPen(leadpen);
200  painter.drawLine(actualindex+label_width+2,(int)(vertical_step*(i+1)-1),actualindex+label_width+2,(int)(vertical_step*(i+1)-1)-(int)(vertical_step-panning_width));
201 }
202 
203 void EvoDataViewer::resizeEvent(QResizeEvent *evt)
204 {
205 
206  evt->accept();
207  if (qpixmap!=NULL) delete qpixmap;
208  qpixmap=new QPixmap(width(), height());
209  reset();
210 }
211 
212 void EvoDataViewer::paintEvent(QPaintEvent *evt)
213 {
214  evt->accept();
215  int offx,offy;
216  offx=0;
217  offy=0;
218  if (pickY<20) offy=20-pickY;
219  if ((width()-pickX)<50) offx=-60;
220 
221  QPainter painter(this);
222  painter.drawPixmap(0, 0, width(), height(), *qpixmap);
223  if(pickValueVisible)
224  {
225  QPen bpen(Qt::black);
226  painter.drawText(pickX+offx,pickY+offy,QString("Val : ")+QString::number(pickValue));
227  painter.drawText(pickX+offx,pickY+10+offy,QString("Step: ")+QString::number(pickStep));
228  }
229 }
230 
232 void EvoDataViewer::setChunkLabel(int ch, const QString &label)
233 {
234  dataChunks[ch]->setLabel(label);
235 }
236 
238 void EvoDataViewer::setChunkValue(int ch, double value)
239 {
240  if ((ch >= 0) && (ch < this->nchunks)) {
241  dataChunks[ch]->setData(value);
242  updateGraphic(ch);
243  }
244 }
245 
247 bool EvoDataViewer::setChunkValue(const QString& name, double value)
248 {
249 
250  for(int i=0;i<nchunks;i++)
251  {
252  if(name == dataChunks[i]->getLabel())
253  {
254  setChunkValue(i, value);
255  return true;
256  }
257  }
258  return false;
259 }
260 
261 
263 void EvoDataViewer::setChunkRange(int ch, double mn, double mx)
264 {
265  dataChunks[ch]->setRange(mn, mx);
266 }
267 
268 void EvoDataViewer::mousePressEvent(QMouseEvent* evt)
269 {
270  if(evt->button()==Qt::LeftButton) {
271  const int xc = evt->x();
272  const int yc = evt->y();
273  const int nochunk = (float(yc) / vertical_step);
274  if (nochunk >= nvchunks) {
275  return;
276  }
277 
278  const int chunkIndex = xc - label_width;
279  const int dataIndex = (int)((float)chunkIndex/dataChunks[vchunks[nochunk]]->getDPRatio());
280  if ((dataIndex < 0) || (dataIndex >= chunksize)) {
281  return;
282  }
283  float val = dataChunks[vchunks[nochunk]]->getValue(dataIndex);
284  val = dataChunks[vchunks[nochunk]]->linearMap(val,0.0, 1.0,dataChunks[vchunks[nochunk]]->getRangeMin(), dataChunks[vchunks[nochunk]]->getRangeMax());
285 
286  pickX = xc;
287  pickY = yc;
288  pickValue = val;
289  pickStep = (int)stepChunk->getValue((int)((float)chunkIndex/dataChunks[vchunks[nochunk]]->getDPRatio()));
290  pickValueVisible = true;
291  qtimer->start();
292 
293  update();
294  }
295 
296  if(evt->button()==Qt::RightButton) {
297  if(elw==NULL) {
298  elw = new EvoListViewer (this->dataChunks,this->nchunks, &this->nviewChange);
299  } else {
300  elw->restoreSelected();
301  elw->setVisible(true);
302  }
303  }
304 }
305 
307 void EvoDataViewer::pickUnvisible()
308 {
309  pickValueVisible=false;
310  qtimer->stop();
311  update();
312 }
313 
318 {
319  stepChunk->setDataRaw(step);
320 
321 }
323 void EvoDataViewer::setStyle(int style)
324 {
325  switch (style)
326  {
327  case 0:
328  style=0;
329  break;
330  case 1:
331  style=1;
332  break;
333  default:
334  style=1;
335  break;
336 
337  }
338 
339 }
340 int EvoDataViewer::visibleChunks()
341 {
342  int vchunks=0;
343  for(int i=0;i<nchunks;i++)
344  if(dataChunks[i]->isVisible())
345  vchunks++;
346  nvchunks=vchunks;
347  return vchunks;
348 }
349 
352 {
353  int vi=0;
354  for(int i=0;i<this->nchunks;i++)
355  {
356  if (dataChunks[i]->isVisible())
357  {
358  this->vchunks[vi]=i;
359  vi++;
360  }
361 
362  }
363  this->nvchunks=vi;
364  vertical_step=height()/(double)nvchunks;
365 }
366 
367 void EvoDataViewer::setChunkColor(int ch, QColor color)
368 {
369  dataChunks[ch]->setColor(color);
370 }
372 void EvoDataViewer::setChunkProperties(int ch, double rangeMin, double rangeMax, const QString &label, QColor color, bool visible)
373 {
374  dataChunks[ch]->setRange(rangeMin, rangeMax);
375  dataChunks[ch]->setLabel(label);
376  dataChunks[ch]->setColor(color);
377  dataChunks[ch]->setVisible(visible);
378 
379 }
382 {
383  this->listVisibleChunks();
384  vertical_step=height()/(double)nvchunks;
385  //
386  for(int i=0;i<nchunks;i++)
387  {
388  //dataChunks[i]->setDSize(width()-label_width);
389  dataChunks[i]->setDPRatio((double)(width()-label_width)/(double)chunksize);
390  }
391 
392  evoDataPaint();
393 }
394 // DataChunk implementation -------------------------------------------------------------------------------------------------------
395 
396 DataChunk::DataChunk(const QString& lab, const QColor& col, int s, bool vis)
397  : color(col)
398  , label(lab)
399  , size(s)
400  , dpratio(1)
401  , visible(vis)
402  , index(-1)
403  , min(0)
404  , max(1)
405  , maxValue(-9999.00)
406  , style(0)
407  , data(NULL)
408  , zeroValue(0.0)
409 {
410  data= new double[size];
411  this->index=-1;
412  for(int i=0;i<size;i++) {
413  data[i]=0;
414  }
415 }
416 
417 DataChunk::~DataChunk()
418 {
419  delete[] data;
420 }
421 
422 void DataChunk::setColor(QColor color)
423 {
424  this->color=color;
425 
426 }
427 
428 void DataChunk::setData(double value)
429 {
430  index++;
431 
432  data[index]=linearMap(value, min, max);
433  checkMaxValue(data[index]);
434  //index++;
435  if(index>size-2) index=-1;
436 
437 }
438 void DataChunk::setDataRaw(double value)
439 {
440  index++;
441  data[index]=value;
442  checkMaxValue(value);
443 
444  //index++;
445  if(index>size-2) index=-1;
446 }
447 void DataChunk::setDataRaw(int ind, double value)
448 {
449  if(ind>-1 && ind<size)
450  data[ind]=value;
451  checkMaxValue(value);
452 }
453 
454 void DataChunk::setLabel(const QString& label)
455 {
456  this->label=label;
457 }
458 
459 void DataChunk::setRange(double min, double max)
460 {
461  this->min=min;
462  this->max=max;
463  zeroValue=linearMap(0.0,min,max);
464 }
465 
466 void DataChunk::setStyle(int style)
467 {
468  this->style = style;
469 
470 }
471 QString DataChunk::getLabel() const
472 {
473 
474  return this->label; // + "=" + QString::number(data[index]);
475 }
476 
477 
478 double DataChunk::getValueToDraw()
479 {
480  return data[index];
481 }
482 
483 int DataChunk::getIndex()
484 {
485  return index;
486 
487 }
488 double DataChunk::linearMap(double x, double rmin, double rmax, double outMin, double outMax)
489 {
490  //Reusing here Gianluca Masssera's code.
491  double m = ( outMax-outMin )/( rmax-rmin );
492  double q = outMin - m*rmin;
493  double ret = m*x+q;
494  if (ret < outMin) return outMin;
495  if (ret > outMax) return outMax;
496  return ret;
497 
498 
499 }
500 
501 double DataChunk::getRangeMin()
502 {
503  return min;
504 }
505 
506 
507 double DataChunk::getRangeMax()
508 {
509  return max;
510 }
511 
512 double DataChunk::getZeroValue()
513 {
514  return zeroValue;
515 }
516 
517 void DataChunk::setDPRatio(double val)
518 {
519  dpratio=val;
520  this->index=-1;
521 }
522 
523 double DataChunk::getDPRatio()
524 {
525  return dpratio;
526 }
527 
528 double DataChunk::getValue(int ind)
529 {
530  return data[ind];
531 }
532 
533 bool DataChunk::isVisible()
534 {
535  return visible;
536 }
537 
538 void DataChunk::setVisible(bool vis)
539 {
540  visible=vis;
541 }
542 QColor& DataChunk::getColor()
543 {
544  return color;
545 }
546 double DataChunk::getMaxValue()
547 {
548  return maxValue;
549 }
550 
551 namespace __DataChunk_loadRawData_helpers {
552  // This has been copied from Factory::orderByNumberAfterColon. Perhaps we could put this function into an utility
553  // library, instead of copying it around...
554  bool orderByNumberAfterColon(const QString& s1, const QString& s2)
555  {
556  // If a string doesn't contain any colon, it always follows the other string; this way strings without colons are always
557  // at the end when sorting
558  QStringList list = s1.split(':', QString::SkipEmptyParts);
559  if (list.size() < 2) {
560  return false;
561  }
562  const double ns1 = list[1].toDouble();
563  list = s2.split(':', QString::SkipEmptyParts);
564  if (list.size() < 2) {
565  return true;
566  }
567  const double ns2 = list[1].toDouble();
568 
569  return (ns1 < ns2);
570  }
571 }
572 void DataChunk::checkMaxValue(double val)
573 {
574  if(val>maxValue) maxValue=val;
575 }
576 bool DataChunk::loadRawData(const QString &filename, int column)
577 {
578  // Tomassino: this is really ugly, but I have no better (and quick to implement) idea for the moment
579  if (filename.endsWith(".fit", Qt::CaseInsensitive)) {
580  index = 0;
581  QFile file(filename);
582  QString line;
583  if(file.open(QIODevice::ReadOnly)) {
584  QTextStream in(&file);
585  line = in.readLine();
586 
587  while(!line.isNull()) {
588  //process line
589  QStringList list;
590  list = line.split(" ");
591  if (column<0 && column>=list.size()) {
592  Logger::error(QString("column number %1 does not exist in the loaded file.").arg(column));
593  return false;
594  }
595 
596  QString value=(QString)list.at(column);
597  setDataRaw(index, value.toDouble());
598  index++;
599 
600  line=in.readLine();
601  }
602  file.close();
603 
604  return true;
605  }
606  } else {
607  // Trying to load using ConfigurationParameters
608  farsa::ConfigurationParameters params(true);
609 
610  if (!params.loadParameters(filename)) {
611  return false;
612  }
613 
614  // Getting the parameter name corresponding to the given column
615  QString paramName;
616  switch (column) {
617  case 0:
618  paramName = "bestFitness";
619  break;
620  case 1:
621  paramName = "averageFitness";
622  break;
623  case 2:
624  paramName = "worstFitness";
625  break;
626  default:
627  paramName = "Unknown";
628  break;
629  }
630 
631  // Here we look for all the groups named GENOTYPES:<number> and read some parameters from each
632  QStringList genotypes = params.getGroupsWithPrefixList("/", "GENOTYPES:");
633 
634  qSort(genotypes.begin(), genotypes.end(), __DataChunk_loadRawData_helpers::orderByNumberAfterColon);
635  index = 0;
636  for (int i = 0; i < genotypes.size(); i++) {
637  setDataRaw(index, params.getValue(genotypes[i] + farsa::ConfigurationParameters::GroupSeparator() + paramName).toDouble());
638  index++;
639  }
640 
641  return true;
642  }
643 
644  //use the return value to give feedback instead of standard output
645  return false;
646 }
647 
648 
649 
650 // implementing EvoListViewer -----------------------------------------------------------------------------------------------------
651 
652 EvoListViewer::EvoListViewer(DataChunk **dataChunks, int n, bool *nviewChange , QWidget *parent) :
653  QWidget(parent)
654 {
655  this->dataChunks=dataChunks;
656  this->nchunks=n;
657  this->nvchange=nviewChange;
658  QListWidgetItem *listItem;
659 
660 
661  layout=new QGridLayout();
662  listwidget = new QListWidget();
663  deselectAll = new QPushButton("deselect all");
664  QPushButton *bcancel = new QPushButton("cancel");
665  QPushButton *bok = new QPushButton("ok");
666  for(int i=0;i<n;i++)
667  {
668  //listwidget->insertItem(i,dataChunks[i]->getLabel());
669  listwidget->insertItem(i, new QListWidgetItem());
670 
671  listItem=listwidget->item(i);
672  listItem->setText(dataChunks[i]->getLabel());
673  Qt::ItemFlags mflags;
674  mflags= Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
675  listItem->setFlags(mflags);
676  listItem->setCheckState(Qt::Checked);
677  }
678 
679  //listwidget.insertItem(3,"terzo");
680 
681 
682  layout->addWidget(deselectAll, 0,0);
683  layout->addWidget(listwidget,1,0);
684  layout->addWidget(bcancel,2,0);
685  layout->addWidget(bok,3,0);
686 
687 
688 
689  this->setLayout(layout);
690  this->setWindowTitle("Chunks List");
691 
692  this->setGeometry(50,50,250,300);
693  this->setVisible(true);
694 
695  //QObject::connect(qtimer,SIGNAL(timeout()),this,SLOT(pickUnvisible()));
696  QObject::connect(bok,SIGNAL(clicked()),this,SLOT(okSelected()));
697  QObject::connect(bcancel,SIGNAL(clicked()),this,SLOT(restoreSelected()));
698  QObject::connect(deselectAll, SIGNAL(clicked()),this,SLOT(allOnOrAllOff()));
699 
700  //setting up the gui
701 
702 
703 
704 
705 
706 }
707 
708 void EvoListViewer::okSelected()
709 {
710  for(int i=0;i<nchunks;i++)
711  {
712  if(this->listwidget->item(i)->checkState()== Qt::Checked)
713  dataChunks[i]->setVisible(true);
714  else
715  dataChunks[i]->setVisible(false);
716  }
717  this->setVisible(false);
718  *nvchange=true;
719 }
720 
721 void EvoListViewer::restoreSelected()
722 {
723  //reset choices
724  this->setVisible(false);
725  for(int i=0;i<nchunks;i++)
726  {
727  if(dataChunks[i]->isVisible())
728  this->listwidget->item(i)->setCheckState(Qt::Checked);
729  else
730  this->listwidget->item(i)->setCheckState(Qt::Unchecked);
731 
732 
733  }
734 }
735 
736 void EvoListViewer::allOnOrAllOff()
737 {
738  bool someoneIsChecked = false;
739  for(int i=0;i<nchunks;i++) //check if there are checked items
740  {
741  if(listwidget->item(i)->checkState() == Qt::Checked)
742  someoneIsChecked = true;
743  }
744 
745  bool select;
746  if(someoneIsChecked) //some item(s) is checked
747  {
748  select = false;
749  deselectAll->setText("select all");
750  }
751  else //there are no checked items
752  {
753  select = true;
754  deselectAll->setText("deselect all");
755  }
756 
757  for(int i=0;i<nchunks;i++)
758  {
759  if(select)
760  this->listwidget->item(i)->setCheckState(Qt::Checked);
761  else
762  this->listwidget->item(i)->setCheckState(Qt::Unchecked);
763  }
764 }
765 
766 /*
767 void EvoListViewer::resizeEvent(QResizeEvent *evt)
768 {
769  //layout->
770 }
771 */
772 
773 EvoListViewer::~EvoListViewer()
774 {
775  delete listwidget;
776  delete layout;
777 
778 
779 }
780 
781 //___________________ FitViewer
782 
783 void FitViewer::setValues(int gen, double min, double average, double max)
784 {
785 
786  fitVal[gen][0]=min;
787  fitVal[gen][1]=average;
788  fitVal[gen][2]=max;
789  currentGen=gen;
790 
791  //checking minimum and maximum
792  //if (min<vmin) vmin=min;
793  //if (max>vmax) vmax=max;
794  checkGraphRange(min);
795  checkGraphRange(average);
796  checkGraphRange(max);
797 
798 
799 
800 }
801 int FitViewer::checkGraphRange(double val)
802 {
803  int ret=0;
804  if (val<vmin)
805  {
806  vmin=val;
807  ret++;
808  }
809  if (val>vmax)
810  {
811  vmax=val;
812  ret++;
813  }
814  return ret;
815 }
816 
817 void FitViewer::checkChunkRange(int chunk)
818 {
819  //for(int i=0;i<nchunks;i++)
820  for(int c=0;c<=currentGen;c++)
821  checkGraphRange(dataChunks[chunk]->getValue(c));
822 }
823 
824 FitViewer::FitViewer( QWidget* parent, Qt::WindowFlags flags ) : QWidget( parent, flags )
825 {
826 
827  padding=50;
828  reset();
829 
830  sortedIndex = NULL;
831  dataChunks = NULL;
832 }
833 
834 FitViewer::FitViewer(int nchunks, int chunksize, QWidget* parent, Qt::WindowFlags flags) : QWidget( parent, flags )
835 {
836 
837  padding=100;
838  reset();
839  this->nchunks=nchunks;
840  this->chunksize=chunksize;
841  currentGen=0;
842  sortedIndex=new int[nchunks];
843  dataChunks = new DataChunk*[nchunks];
844  for(int i=0;i<nchunks;i++) {
845  dataChunks[i] = new DataChunk(QString("chunk"),QColor(255,0,0),chunksize, true);
846  sortedIndex[i]=i;
847  }
848 }
849 
850 FitViewer::~FitViewer()
851 {
852  delete[] sortedIndex;
853  if (dataChunks != NULL) {
854  for (int i = 0; i < nchunks; i++) {
855  delete dataChunks[i];
856  }
857  delete[] dataChunks;
858  }
859 }
860 
861 void FitViewer::paintEvent(QPaintEvent* /*evt*/)
862 {
863  QPainter painter(this);
864  QPen blackPen(Qt::black);
865  QPen bluePen(Qt::blue);
866  QPen greenPen(Qt::green);
867  QPen redPen(Qt::red);
868  int xt,yt;
869 
870  painter.fillRect(0,0,width(),height(),Qt::white);
871  painter.setPen(blackPen);
872  painter.setRenderHint(QPainter::Antialiasing, false);
873  xstep=(double)(width()-2*padding)/(double)(currentGen);
874  wyaxes=height()-2*padding;
875 
876  painter.drawRect(padding,padding,width()-2*padding,height()-2*padding);
877  if (vmin>0) zeroy=height()-padding;
878  else
879  {
880  zeroy=((-1*vmin)/(vmax-vmin))*wyaxes;
881  }
882 
883  painter.drawLine(padding,height()-padding-zeroy,width()-padding,height()-padding-zeroy);
884  painter.drawText(padding/2.0,padding,QString::number(vmax));
885  painter.drawText(padding/2.0,height()-padding,QString::number(vmin));
886  painter.drawText(padding/2.0,height()-padding-zeroy,QString::number(0));
887 
888  //drawing zero axes
889  painter.drawText(width()-padding,height()-padding-zeroy,QString::number(currentGen));
890 
891  //graph title
892  painter.drawText(width()/2.0-padding,padding/2.0,gtitle);
893 
894  //drawing xlabel
895  painter.drawText(width()/2.0-padding,height()-padding/2.0,xlabel);
896 
897  //drawing ylabel
898  xt=padding/4.0;
899  yt=height()/2.0;
900  painter.save();
901  painter.translate(xt,yt);
902  painter.rotate(-90.0);
903  painter.drawText(0,0,ylabel);
904  painter.restore();
905 
906 
907  /*
908  painter.setPen(bluePen);
909  painter.drawText(width()/2.0,padding/4.0*3,"Minimum");
910  painter.setPen(greenPen);
911  painter.drawText(width()/2.0,padding/4.0*2,"Average");
912  painter.setPen(redPen);
913  painter.drawText(width()/2.0,padding/4.0*1,"Maximum");
914  */
915 
916  painter.setRenderHint(QPainter::Antialiasing, true);
917  for (int dc=0;dc<nchunks;dc++)
918  {
919  int c=sortedIndex[dc];
920  painter.setPen(dataChunks[c]->getColor());
921  painter.drawText(width()-padding+2,padding+dc*20,dataChunks[c]->getLabel());
922 
923  for (int i=1;i<currentGen+1;i++)
924  {
925  /*
926  painter.setPen(bluePen);
927  painter.drawLine(padding+xstep*(i-1), height()-padding-getYnormValue(fitVal[i-1][0]),padding+xstep*i,height()-padding-getYnormValue(fitVal[i][0]));
928  painter.setPen(greenPen);
929  painter.drawLine(padding+xstep*(i-1), height()-padding-getYnormValue(fitVal[i-1][1]),padding+xstep*i,height()-padding-getYnormValue(fitVal[i][1]));
930  painter.setPen(redPen);
931  painter.drawLine(padding+xstep*(i-1), height()-padding-getYnormValue(fitVal[i-1][2]),padding+xstep*i,height()-padding-getYnormValue(fitVal[i][2]));
932  */
933 
934  checkGraphRange(dataChunks[c]->getValue(i-1));
935  painter.drawLine(padding+xstep*(i-1), height()-padding-getYnormValue(dataChunks[c]->getValue(i-1)),padding+xstep*i,height()-padding-getYnormValue(dataChunks[c]->getValue(i)));
936 
937 
938  }
939  }
940 
941 }
942 
943 double FitViewer::getYnormValue(double val)
944 {
945  if(vmin>0)
946  {
947  return (val/vmax)*wyaxes;
948  }
949  else
950  {
951 
952  return ((val-vmin)/(vmax-vmin))*wyaxes;
953 
954  }
955 }
956 
957 void FitViewer::setChunkLabel(int ch, const QString &label)
958 {
959 
960  dataChunks[ch]->setLabel(label);
961 }
962 void FitViewer::setChunkProperties(int ch, const QString &label, QColor color, bool visible)
963 {
964  dataChunks[ch]->setLabel(label);
965  dataChunks[ch]->setColor(color);
966  dataChunks[ch]->setVisible(visible);
967 }
968 
969 void FitViewer::setChunkValue(int ch,int ind, double value)
970 {
971  if (ch>= 0 && ch < this->nchunks)
972  {
973  dataChunks[ch]->setDataRaw(ind,value);
974  checkGraphRange(value);
975  }
976 }
977 
978 bool FitViewer::setChunkValue(const QString &name,int ind, double value)
979 {
980  for(int i=0;i<nchunks;i++)
981  {
982  if(name == dataChunks[i]->getLabel())
983  {
984  setChunkValue(i,ind, value);
985  checkGraphRange(value);
986  return true;
987  }
988  }
989  return false;
990 
991 }
992 void FitViewer::diplayUntilStep(int st)
993 {
994  currentGen=st;
995 }
996 
997 void FitViewer::setLabels(const QString &title, const QString &xlabel, const QString &ylabel)
998 {
999  this->gtitle=title;
1000  this->xlabel=xlabel;
1001  this->ylabel=ylabel;
1002 }
1003 
1004 void FitViewer::reset()
1005 {
1006  vmin=-0.0;
1007  vmax=0.0;
1008  padding=90;
1009  setMinimumSize(padding*4,padding*4);
1010  currentGen=0;
1011 }
1012 
1013 bool FitViewer::loadRawData(int nchunk, const QString &filename, int column)
1014 {
1015  bool res;
1016  res=dataChunks[nchunk]->loadRawData(filename,column);
1017  if(res)
1018  {
1019  //currentGen=dataChunks[nchunk]->getIndex()-1;
1020  if((dataChunks[nchunk]->getIndex()-1)>currentGen) currentGen=dataChunks[nchunk]->getIndex()-1;
1021  }
1022  checkChunkRange(nchunk);
1023  return res;
1024 }
1025 
1026 int FitViewer::getCurrentGeneration()
1027 {
1028  return currentGen;
1029 }
1030 
1031 void FitViewer::sortchunks()
1032 {
1033  bool swap=true;
1034  for(int i=0;i<nchunks;i++)
1035  {
1036  sortedIndex[i]=i;
1037  }
1038 
1039  while (swap)
1040  {
1041  swap=false;
1042  int s;
1043  for(int i=0;i<nchunks-1;i++)
1044  {
1045  if (dataChunks[sortedIndex[i]]->getMaxValue()<dataChunks[sortedIndex[i+1]]->getMaxValue())
1046  {
1047  s=sortedIndex[i];
1048  sortedIndex[i]=sortedIndex[i+1];
1049  sortedIndex[i+1]=s;
1050  swap=true;
1051  }
1052  }
1053  }
1054 }
1055 
1056 } //end namespace farsa
void setChunkValue(int ch, double value)
set chunk value by chunck id
void listVisibleChunks()
Creates a list of the visible chunks.
void setChunkRange(int ch, double mn, double mx)
set the range of the incoming data
void setCurrentStep(int step)
it stores the current step for each value.
void setChunkLabel(int ch, const QString &label)
set the chunk label
FARSA_UTIL_TEMPLATE const T max(const T &t1, const U &t2)
void setChunkProperties(int ch, double rangeMin, double rangeMax, const QString &label, QColor color, bool visible)
Set all the chunk properties in one step.
static void error(QString msg)
void setStyle(int style)
set the drawing style 0: filled lines, 1: simple line
EvoDataViewer(int nchunks, int chunksize, int style=0, QWidget *parent=0, Qt::WindowFlags flags=0)
EvodaViewer constructor.
FARSA_UTIL_TEMPLATE const T min(const T &t1, const U &t2)
static QString GroupSeparator()
void reset()
Cleans the screen and resets chunk indexes in order to display new data.