experiments/evorobot/src/evodataviewer.cpp

00001 /********************************************************************************
00002  *  FARSA Experiments Library                                                   *
00003  *  Copyright (C) 2007-2012                                                     *
00004  *  Stefano Nolfi <stefano.nolfi@istc.cnr.it>                                   *
00005  *  Onofrio Gigliotta <onofrio.gigliotta@istc.cnr.it>                           *
00006  *  Gianluca Massera <emmegian@yahoo.it>                                        *
00007  *  Tomassino Ferrauto <tomassino.ferrauto@istc.cnr.it>                         *
00008  *                                                                              *
00009  *  This program is free software; you can redistribute it and/or modify        *
00010  *  it under the terms of the GNU General Public License as published by        *
00011  *  the Free Software Foundation; either version 2 of the License, or           *
00012  *  (at your option) any later version.                                         *
00013  *                                                                              *
00014  *  This program is distributed in the hope that it will be useful,             *
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of              *
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
00017  *  GNU General Public License for more details.                                *
00018  *                                                                              *
00019  *  You should have received a copy of the GNU General Public License           *
00020  *  along with this program; if not, write to the Free Software                 *
00021  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  *
00022  ********************************************************************************/
00023 
00024 #include "evodataviewer.h"
00025 
00026 #include <QPainter>
00027 #include <QPen>
00028 #include <QPaintEvent>
00029 #include <QApplication>
00030 #include <QScrollArea>
00031 #include <QDebug>
00032 #include <QStringList>
00033 #include <QtGui>
00034 #include <QtAlgorithms>
00035 #include <configurationparameters.h>
00036 #include "logger.h"
00037 
00038 namespace farsa {
00039 
00041 EvoDataViewer::EvoDataViewer(int nchunks, int chunksize, int style, QWidget* parent, Qt::WindowFlags flags) :
00042     QWidget(parent,flags)
00043 {
00044     //to do: put this stuff within a method
00045     this->style=style;
00046     panning_width=4;
00047     label_width=100;
00048     this->setMaximumWidth(chunksize+label_width);
00049     this->setMinimumWidth(label_width*2);
00050     this->setMinimumHeight(10*nchunks);
00051     this->nviewChange=false;
00052     vchunks=new int[nchunks];
00053 
00054     this->setAttribute(Qt::WA_OpaquePaintEvent, true);
00055 
00056     qpixmap = new QPixmap(width(), height());
00057 
00058     //initialiazing datachunks
00059     this->nchunks = nchunks;
00060     this->chunksize = chunksize;
00061     this->nvchunks=nchunks;
00062 
00063      dataChunks = new DataChunk*[nchunks];
00064     for(int i=0;i<nchunks;i++)
00065     {
00066     dataChunks[i] = new DataChunk(QString("chunk"),QColor(255,0,0),chunksize, true);
00067     }
00068 
00069     stepChunk=new DataChunk(QString("step"),QColor(255,0,0),chunksize, false);
00070     
00071     this->setChunkLabel(0,"Input");
00072 
00073     this->listVisibleChunks();
00074 
00075     qtimer=new QTimer(this);
00076     qtimer->setInterval(4000);
00077     QObject::connect(qtimer,SIGNAL(timeout()),this,SLOT(pickUnvisible()));
00078 
00079     elw=NULL;
00080     
00081 
00082     pickY = 0;
00083     pickX = 0;
00084     pickValueVisible = false;
00085 
00086 }
00087 EvoDataViewer::~EvoDataViewer()
00088 {
00089     for(int i=0;i<nchunks;i++) {
00090         delete dataChunks[i];
00091     }
00092     delete[] dataChunks;
00093 
00094     delete stepChunk;
00095 
00096     delete qpixmap;
00097     delete elw;
00098 }
00099 
00101 void EvoDataViewer::evoDataPaint()
00102 {
00103     //draws background and labels and axes
00104     QPainter painter(qpixmap);
00105     QPen pen(Qt::black, 1);
00106     QPen pen2(Qt::lightGray);
00107     QPen pen3(Qt::darkGray);
00108     painter.setPen(pen);
00109     int hh;
00110     
00111     painter.fillRect(0,0,width(),height(),Qt::white); 
00112     
00113     for(int i=0;i<nvchunks+1;i++)
00114     {
00115     
00116     painter.setPen(pen);
00117         if (i<nvchunks)
00118         {
00119         painter.drawText(4,(int)(vertical_step*(i+1)-vertical_step/2.0),dataChunks[vchunks[i]]->getLabel());
00120         painter.drawText(label_width-40,(int)(vertical_step*(i+1))-4,QString::number(dataChunks[vchunks[i]]->getRangeMin()));
00121         painter.drawText(label_width-40,(int)(vertical_step*(i+1))-4-(int)(vertical_step-20),QString::number(dataChunks[vchunks[i]]->getRangeMax()));
00122         }
00123     //drawing range
00124     
00125     painter.drawLine(0,(int)(vertical_step*i),width(),(int)(vertical_step*i));
00126     
00127     painter.setPen(pen3);
00128     painter.drawLine(0,(int)(vertical_step*i+1),width(),(int)(vertical_step*i+1));
00129 
00130     painter.setPen(pen2);
00131     painter.drawLine(0,(int)(vertical_step*i+2),width(),(int)(vertical_step*i+2));
00132     //  painter.drawLine(50,50,400,400);
00133     //painter.drawText(4,(int)(vertical_step*i),dataChunks[i]->
00134 
00135     }
00136 
00137     hh=(int)(vertical_step*(nvchunks));
00138     painter.setPen(pen);
00139     
00140     painter.drawLine(label_width-1,0,label_width-1,hh);
00141     painter.setPen(pen2);
00142     
00143     painter.drawLine(label_width,0,label_width,hh);
00144     painter.drawLine(label_width-2,0,label_width-2,hh);
00145 }
00146 
00148 void EvoDataViewer::updateGraphic(int ch)
00149 {
00150     if (nviewChange) {
00151         reset();
00152         nviewChange = false;
00153     }
00154 
00155     if (!dataChunks[ch]->isVisible()) {
00156         // If the chunk is not visible, we have nothing to do
00157         return;
00158     }
00159 
00160     QPainter painter(qpixmap);
00161     const QPen pen(Qt::red);
00162     const QPen penw(Qt::white);
00163     const QPen leadpen(Qt::black);
00164 
00165     // Computing the index of the chunk excluding invisible ones
00166     int i = 0;
00167     for (int ii = 0; ii < ch; ii++) {
00168         if (dataChunks[ii]->isVisible()) {
00169             i++;
00170         }
00171     }
00172 
00173     int actualindex = -1;
00174     int predindex;
00175 
00176     if(dataChunks[i]->getIndex() > -1) {
00177         actualindex=(int)(dataChunks[vchunks[i]]->getIndex()*dataChunks[vchunks[i]]->getDPRatio());
00178         predindex=(int)((dataChunks[vchunks[i]]->getIndex()-1)*dataChunks[vchunks[i]]->getDPRatio());
00179         painter.setPen(pen);
00180 
00181         QPen personalpen(dataChunks[vchunks[i]]->getColor());
00182         painter.setPen(personalpen);
00183 
00185         int zeropoint=(int)((vertical_step-panning_width-1)*dataChunks[vchunks[i]]->getZeroValue());
00186 
00187         if (style == 0) {
00188             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)));
00189         } else if (style == 1) {
00190             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)));
00191         }
00192 
00193     }
00194 
00195     //white line
00196     painter.setPen(penw);
00197     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));
00198 
00199     //lead line
00200     painter.setPen(leadpen);
00201     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));
00202 }
00203 
00204 void EvoDataViewer::resizeEvent(QResizeEvent *evt)
00205 {
00206     
00207     evt->accept();
00208     if (qpixmap!=NULL) delete qpixmap;
00209     qpixmap=new QPixmap(width(), height());
00210     reset();
00211 }
00212 
00213 void EvoDataViewer::paintEvent(QPaintEvent *evt)
00214 {   
00215     evt->accept();
00216     int offx,offy;
00217     offx=0;
00218     offy=0;
00219     if (pickY<20) offy=20-pickY;
00220     if ((width()-pickX)<50) offx=-60;
00221 
00222     QPainter painter(this);
00223     painter.drawPixmap(0, 0, width(), height(), *qpixmap);
00224     if(pickValueVisible)
00225     {   
00226         QPen bpen(Qt::black);
00227         painter.drawText(pickX+offx,pickY+offy,QString("Val : ")+QString::number(pickValue));
00228         painter.drawText(pickX+offx,pickY+10+offy,QString("Step: ")+QString::number(pickStep));
00229     }
00230 }
00231 
00233 void EvoDataViewer::setChunkLabel(int ch, const QString &label)
00234 {
00235     dataChunks[ch]->setLabel(label);
00236 }
00237 
00239 void EvoDataViewer::setChunkValue(int ch, double value)
00240 {
00241     if ((ch >= 0) && (ch < this->nchunks)) {
00242         dataChunks[ch]->setData(value);
00243         updateGraphic(ch);
00244     }
00245 }
00246 
00248 bool EvoDataViewer::setChunkValue(const QString& name, double value)
00249 {
00250     
00251     for(int i=0;i<nchunks;i++)
00252     {
00253         if(name == dataChunks[i]->getLabel())
00254         {
00255             setChunkValue(i, value);
00256             return true;
00257         }
00258     }
00259     return false;
00260 }
00261 
00262 
00264 void EvoDataViewer::setChunkRange(int ch, double mn, double mx)
00265 {
00266     dataChunks[ch]->setRange(mn, mx);
00267 }
00268 
00269 void EvoDataViewer::mousePressEvent(QMouseEvent* evt)
00270 {
00271     //
00272     if(evt->button()==Qt::LeftButton)
00273     {
00274     int xc = evt->x();
00275     int yc = evt->y();
00276     int nochunk = ((float)yc/vertical_step);
00277     if (nochunk >= nvchunks) {
00278         return;
00279     }
00280     int chunkIndex = xc-label_width;
00281     float val=dataChunks[vchunks[nochunk]]->getValue((int)((float)chunkIndex/dataChunks[vchunks[nochunk]]->getDPRatio()));
00282     val = dataChunks[vchunks[nochunk]]->linearMap(val,0.0, 1.0,dataChunks[vchunks[nochunk]]->getRangeMin(), dataChunks[vchunks[nochunk]]->getRangeMax());
00283     
00284 
00285     pickX=xc;
00286     pickY=yc;
00287     pickValue=val;
00288     pickStep = (int)stepChunk->getValue((int)((float)chunkIndex/dataChunks[vchunks[nochunk]]->getDPRatio()));
00289     pickValueVisible=true;
00290     qtimer->start();
00291 
00292     update();
00293     }
00294 
00295         if(evt->button()==Qt::RightButton)
00296     {
00297         if(elw==NULL)
00298         elw = new EvoListViewer (this->dataChunks,this->nchunks, &this->nviewChange);
00299         
00300         else
00301         {
00302         elw->restoreSelected(); 
00303         elw->setVisible(true);
00304         }
00305     }
00306     
00307 
00308 }
00310 void EvoDataViewer::pickUnvisible()
00311 {
00312     pickValueVisible=false;
00313     qtimer->stop();
00314     update();
00315 }
00316 
00320 void EvoDataViewer::setCurrentStep(int step)
00321 {
00322     stepChunk->setDataRaw(step);
00323 
00324 }
00326 void EvoDataViewer::setStyle(int style)
00327 {
00328     switch (style)
00329     {
00330     case 0:
00331         style=0;
00332         break;
00333     case 1:
00334         style=1;
00335         break;
00336     default:
00337         style=1;
00338         break;
00339 
00340     }
00341 
00342 }
00343 int EvoDataViewer::visibleChunks()
00344 {
00345     int vchunks=0;
00346     for(int i=0;i<nchunks;i++)
00347         if(dataChunks[i]->isVisible())
00348             vchunks++;
00349     nvchunks=vchunks;
00350     return vchunks;
00351 }
00352 
00354 void EvoDataViewer::listVisibleChunks()
00355 {
00356     int vi=0;
00357     for(int i=0;i<this->nchunks;i++)
00358     {
00359         if (dataChunks[i]->isVisible())
00360         {
00361             this->vchunks[vi]=i;
00362             vi++;
00363         }
00364 
00365     }
00366     this->nvchunks=vi;
00367     vertical_step=height()/(double)nvchunks;
00368 }
00369 
00370 void EvoDataViewer::setChunkColor(int ch, QColor color)
00371 {
00372     dataChunks[ch]->setColor(color);
00373 }
00375 void EvoDataViewer::setChunkProperties(int ch, double rangeMin, double rangeMax, const QString &label, QColor color, bool visible)
00376 {
00377     dataChunks[ch]->setRange(rangeMin, rangeMax);
00378     dataChunks[ch]->setLabel(label);
00379     dataChunks[ch]->setColor(color);
00380     dataChunks[ch]->setVisible(visible);
00381 
00382 }
00384 void EvoDataViewer::reset()
00385 {
00386     this->listVisibleChunks();
00387     vertical_step=height()/(double)nvchunks;
00388     //
00389     for(int i=0;i<nchunks;i++)
00390     {
00391         //dataChunks[i]->setDSize(width()-label_width);
00392         dataChunks[i]->setDPRatio((double)(width()-label_width)/(double)chunksize);
00393     }
00394 
00395     evoDataPaint();
00396 }
00397 // DataChunk implementation -------------------------------------------------------------------------------------------------------
00398 
00399 DataChunk::DataChunk(const QString&  label, const QColor& color, int size, bool visible)
00400 {
00401     this->label=label;
00402     this->color=color;
00403     this->size=size;
00404     this->visible=visible;
00405     
00406     data= new double[size];
00407     this->index=-1;
00408     for(int i=0;i<size;i++)
00409         data[i]=0;
00410     //by default range is set between 0 and 1
00411     min=0;
00412     max=1; 
00413     zeroValue=0.0;
00414     maxValue=-9999.00;
00415     
00416 
00417 }
00418 DataChunk::~DataChunk()
00419 {
00420     delete[] data;
00421 }
00422 
00423 void DataChunk::setColor(QColor color)
00424 {
00425     this->color=color;
00426 
00427 }
00428 
00429 void DataChunk::setData(double value)
00430 {
00431     index++;
00432     
00433     data[index]=linearMap(value, min, max);
00434     checkMaxValue(data[index]);
00435     //index++;
00436     if(index>size-2) index=-1;
00437     
00438 }
00439 void DataChunk::setDataRaw(double value)
00440 {
00441         index++;
00442     data[index]=value;
00443     checkMaxValue(value);
00444     
00445     //index++;
00446     if(index>size-2) index=-1;
00447 }
00448 void DataChunk::setDataRaw(int ind, double value)
00449 {
00450     if(ind>-1 && ind<size)
00451     data[ind]=value;
00452     checkMaxValue(value);
00453 }
00454 
00455 void DataChunk::setLabel(const QString& label)
00456 {
00457     this->label=label;
00458 }
00459 
00460 void DataChunk::setRange(double min, double max)
00461 {
00462     this->min=min;
00463     this->max=max;
00464     zeroValue=linearMap(0.0,min,max);
00465 }
00466 
00467 void DataChunk::setStyle(int style)
00468 {
00469     this->style = style;
00470 
00471 }
00472 const QString& DataChunk::getLabel()
00473 {
00474 
00475     return this->label;
00476 }
00477 
00478 
00479 double DataChunk::getValueToDraw()
00480 {
00481     return data[index];
00482 }
00483 
00484 int DataChunk::getIndex()
00485 {
00486     return index;
00487 
00488 }
00489 double DataChunk::linearMap(double x, double rmin, double rmax, double outMin, double outMax)
00490 {
00491     //Reusing here Gianluca Masssera's code.
00492     double m = ( outMax-outMin )/( rmax-rmin );
00493     double q = outMin - m*rmin;
00494     double ret = m*x+q;
00495     if (ret < outMin) return outMin;
00496     if (ret > outMax) return outMax;
00497     return ret;
00498 
00499 
00500 }
00501 
00502 double DataChunk::getRangeMin()
00503 {
00504     return min;
00505 }
00506 
00507 
00508 double DataChunk::getRangeMax()
00509 {
00510     return max;
00511 }
00512 
00513 double DataChunk::getZeroValue()
00514 {
00515     return zeroValue;   
00516 }
00517 
00518 void DataChunk::setDPRatio(double val)
00519 {
00520     dpratio=val;
00521     this->index=-1;
00522 }
00523 
00524 double DataChunk::getDPRatio()
00525 {
00526     return dpratio;
00527 }
00528 
00529 double DataChunk::getValue(int ind)
00530 {
00531     return data[ind];
00532 }
00533 
00534 bool DataChunk::isVisible()
00535 {
00536     return visible;
00537 }
00538 
00539 void DataChunk::setVisible(bool vis)
00540 {
00541     visible=vis;
00542 }
00543 QColor& DataChunk::getColor()
00544 {
00545     return color;
00546 }
00547 double DataChunk::getMaxValue()
00548 {
00549     return maxValue;
00550 }
00551 
00552 namespace __DataChunk_loadRawData_helpers {
00553     // This has been copied from Factory::orderByNumberAfterColon. Perhaps we could put this function into an utility
00554     // library, instead of copying it around...
00555     bool orderByNumberAfterColon(const QString& s1, const QString& s2)
00556     {
00557         // If a string doesn't contain any colon, it always follows the other string; this way strings without colons are always
00558         // at the end when sorting
00559         QStringList list = s1.split(':', QString::SkipEmptyParts);
00560         if (list.size() < 2) {
00561             return false;
00562         }
00563         const double ns1 = list[1].toDouble();
00564         list = s2.split(':', QString::SkipEmptyParts);
00565         if (list.size() < 2) {
00566             return true;
00567         }
00568         const double ns2 = list[1].toDouble();
00569 
00570         return (ns1 < ns2);
00571     }
00572 }
00573 void DataChunk::checkMaxValue(double val)
00574 {
00575     if(val>maxValue) maxValue=val;
00576 }
00577 bool DataChunk::loadRawData(const QString &filename, int column)
00578 {
00579     // Tomassino: this is really ugly, but I have no better (and quick to implement) idea for the moment
00580     if (filename.endsWith(".fit", Qt::CaseInsensitive)) {
00581         index = 0;
00582         QFile file(filename);
00583         QString line;
00584         if(file.open(QIODevice::ReadOnly)) {
00585             QTextStream in(&file);
00586             line = in.readLine();
00587 
00588             while(!line.isNull()) {
00589                 //process line
00590                 QStringList list;
00591                 list = line.split(" ");
00592                 if (column<0 && column>=list.size()) {
00593                     Logger::error(QString("column number %1 does not exist in the loaded file.").arg(column));
00594                     return false;
00595                 }
00596 
00597                 QString value=(QString)list.at(column);
00598                 setDataRaw(index, value.toDouble());
00599                 index++;
00600 
00601                 line=in.readLine();
00602             }
00603             file.close();
00604 
00605             return true;
00606         }
00607     } else {
00608         // Trying to load using ConfigurationParameters
00609         farsa::ConfigurationParameters params(true);
00610 
00611         if (!params.loadParameters(filename)) {
00612             return false;
00613         }
00614 
00615         // Getting the parameter name corresponding to the given column
00616         QString paramName;
00617         switch (column) {
00618             case 0:
00619                 paramName = "bestFitness";
00620                 break;
00621             case 1:
00622                 paramName = "averageFitness";
00623                 break;
00624             case 2:
00625                 paramName = "worstFitness";
00626                 break;
00627             default:
00628                 paramName = "Unknown";
00629                 break;
00630         }
00631 
00632         // Here we look for all the groups named GENOTYPES:<number> and read some parameters from each
00633         QStringList genotypes = params.getGroupsWithPrefixList("/", "GENOTYPES:");
00634 
00635         qSort(genotypes.begin(), genotypes.end(), __DataChunk_loadRawData_helpers::orderByNumberAfterColon);
00636         index = 0;
00637         for (int i = 0; i < genotypes.size(); i++) {
00638             setDataRaw(index, params.getValue(genotypes[i] + farsa::ConfigurationParameters::GroupSeparator() + paramName).toDouble());
00639             index++;
00640         }
00641 
00642         return true;
00643     }
00644 
00645     //use the return value to give feedback instead of standard output
00646     return false;
00647 }
00648 
00649 
00650 
00651 // implementing EvoListViewer -----------------------------------------------------------------------------------------------------
00652 
00653 EvoListViewer::EvoListViewer(DataChunk **dataChunks, int n, bool *nviewChange ,  QWidget *parent) :
00654     QWidget(parent)
00655 {
00656     this->dataChunks=dataChunks;
00657     this->nchunks=n;
00658     this->nvchange=nviewChange;
00659     QListWidgetItem *listItem;
00660 
00661     
00662     layout=new QGridLayout();
00663     listwidget = new QListWidget();
00664     deselectAll = new QPushButton("deselect all");
00665     QPushButton *bcancel = new QPushButton("cancel");
00666     QPushButton *bok = new QPushButton("ok");
00667     for(int i=0;i<n;i++)
00668     {
00669     //listwidget->insertItem(i,dataChunks[i]->getLabel());
00670         listwidget->insertItem(i, new QListWidgetItem());
00671         
00672         listItem=listwidget->item(i);
00673         listItem->setText(dataChunks[i]->getLabel());
00674         Qt::ItemFlags mflags;
00675         mflags=  Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
00676         listItem->setFlags(mflags);
00677         listItem->setCheckState(Qt::Checked);
00678     }
00679     
00680     //listwidget.insertItem(3,"terzo");
00681 
00682 
00683     layout->addWidget(deselectAll, 0,0);
00684     layout->addWidget(listwidget,1,0);
00685     layout->addWidget(bcancel,2,0);
00686     layout->addWidget(bok,3,0);
00687     
00688     
00689 
00690     this->setLayout(layout);
00691     this->setWindowTitle("Chunks List");
00692 
00693     this->setGeometry(50,50,250,300);
00694     this->setVisible(true);
00695 
00696     //QObject::connect(qtimer,SIGNAL(timeout()),this,SLOT(pickUnvisible()));
00697     QObject::connect(bok,SIGNAL(clicked()),this,SLOT(okSelected()));
00698     QObject::connect(bcancel,SIGNAL(clicked()),this,SLOT(restoreSelected()));
00699     QObject::connect(deselectAll, SIGNAL(clicked()),this,SLOT(allOnOrAllOff()));
00700 
00701     //setting up the gui
00702     
00703     
00704     
00705 
00706 
00707 }
00708 
00709 void EvoListViewer::okSelected()
00710 {
00711     for(int i=0;i<nchunks;i++)
00712     {
00713         if(this->listwidget->item(i)->checkState()== Qt::Checked)
00714             dataChunks[i]->setVisible(true);
00715         else
00716             dataChunks[i]->setVisible(false);
00717     }
00718     this->setVisible(false);
00719     *nvchange=true;
00720 }
00721 
00722 void EvoListViewer::restoreSelected()
00723 {
00724     //reset choices
00725     this->setVisible(false);
00726     for(int i=0;i<nchunks;i++)
00727     {
00728         if(dataChunks[i]->isVisible())
00729             this->listwidget->item(i)->setCheckState(Qt::Checked);
00730         else
00731             this->listwidget->item(i)->setCheckState(Qt::Unchecked);
00732 
00733         
00734     }
00735 }
00736 
00737 void EvoListViewer::allOnOrAllOff()
00738 {
00739     bool someoneIsChecked = false;
00740     for(int i=0;i<nchunks;i++)  //check if there are checked items
00741     {
00742         if(listwidget->item(i)->checkState() == Qt::Checked)
00743             someoneIsChecked = true;
00744     }
00745 
00746     bool select;
00747     if(someoneIsChecked)    //some item(s) is checked
00748     {
00749         select = false;
00750         deselectAll->setText("select all");
00751     }
00752     else        //there are no checked items
00753     {
00754         select = true;
00755         deselectAll->setText("deselect all");
00756     }
00757 
00758     for(int i=0;i<nchunks;i++)
00759     {
00760         if(select)
00761             this->listwidget->item(i)->setCheckState(Qt::Checked);
00762         else
00763             this->listwidget->item(i)->setCheckState(Qt::Unchecked);    
00764     }
00765 }
00766 
00767 /*
00768 void EvoListViewer::resizeEvent(QResizeEvent *evt)
00769 {
00770     //layout->
00771 }
00772 */
00773 
00774 EvoListViewer::~EvoListViewer()
00775 {
00776     delete listwidget;
00777     delete layout;
00778     
00779     
00780 }
00781 
00782 //___________________ FitViewer
00783 
00784 void FitViewer::setValues(int gen, double min, double average, double max)
00785 {
00786 
00787     fitVal[gen][0]=min;
00788     fitVal[gen][1]=average;
00789     fitVal[gen][2]=max;
00790     currentGen=gen;
00791 
00792     //checking minimum and maximum
00793     //if (min<vmin) vmin=min;
00794     //if (max>vmax) vmax=max;
00795     checkGraphRange(min);
00796     checkGraphRange(average);
00797     checkGraphRange(max);
00798 
00799     
00800 
00801 }
00802 int  FitViewer::checkGraphRange(double val)
00803 {
00804     int ret=0;
00805     if (val<vmin)
00806     {
00807         vmin=val;
00808         ret++;
00809     }
00810     if (val>vmax)
00811     {
00812         vmax=val;
00813         ret++;
00814     }
00815     return ret;
00816 }
00817 
00818 void FitViewer::checkChunkRange(int chunk)
00819 {
00820     //for(int i=0;i<nchunks;i++)
00821         for(int c=0;c<=currentGen;c++)
00822             checkGraphRange(dataChunks[chunk]->getValue(c));
00823 }
00824 
00825 FitViewer::FitViewer( QWidget* parent, Qt::WindowFlags flags ) : QWidget( parent, flags )
00826 {
00827     
00828     padding=50;
00829     reset();
00830 
00831     sortedIndex = NULL;
00832     dataChunks = NULL;
00833 }
00834 
00835 FitViewer::FitViewer(int nchunks, int chunksize, QWidget* parent, Qt::WindowFlags flags) : QWidget( parent, flags )
00836 {
00837     
00838     padding=100;
00839     reset();
00840     this->nchunks=nchunks;
00841     this->chunksize=chunksize;
00842     currentGen=0;
00843     sortedIndex=new int[nchunks];
00844     dataChunks = new DataChunk*[nchunks];
00845     for(int i=0;i<nchunks;i++) {
00846         dataChunks[i] = new DataChunk(QString("chunk"),QColor(255,0,0),chunksize, true);
00847         sortedIndex[i]=i;
00848     }
00849 }
00850 
00851 FitViewer::~FitViewer()
00852 {
00853     delete[] sortedIndex;
00854     if (dataChunks != NULL) {
00855         for (int i = 0; i < nchunks; i++) {
00856             delete dataChunks[i];
00857         }
00858         delete[] dataChunks;
00859     }
00860 }
00861 
00862 void FitViewer::paintEvent(QPaintEvent* /*evt*/)
00863 {
00864     QPainter painter(this); 
00865     QPen blackPen(Qt::black);
00866     QPen bluePen(Qt::blue);
00867     QPen greenPen(Qt::green);
00868     QPen redPen(Qt::red);
00869     int xt,yt;
00870     
00871     painter.fillRect(0,0,width(),height(),Qt::white);
00872     painter.setPen(blackPen);
00873     painter.setRenderHint(QPainter::Antialiasing, false);
00874     xstep=(double)(width()-2*padding)/(double)(currentGen);
00875     wyaxes=height()-2*padding;
00876 
00877     painter.drawRect(padding,padding,width()-2*padding,height()-2*padding);
00878     if (vmin>0) zeroy=height()-padding;
00879     else
00880     {
00881     zeroy=((-1*vmin)/(vmax-vmin))*wyaxes;
00882     }
00883 
00884     painter.drawLine(padding,height()-padding-zeroy,width()-padding,height()-padding-zeroy);
00885     painter.drawText(padding/2.0,padding,QString::number(vmax));
00886     painter.drawText(padding/2.0,height()-padding,QString::number(vmin));
00887     painter.drawText(padding/2.0,height()-padding-zeroy,QString::number(0));
00888 
00889     //drawing zero axes
00890     painter.drawText(width()-padding,height()-padding-zeroy,QString::number(currentGen));
00891 
00892     //graph title
00893     painter.drawText(width()/2.0-padding,padding/2.0,gtitle);
00894 
00895     //drawing xlabel
00896     painter.drawText(width()/2.0-padding,height()-padding/2.0,xlabel);
00897 
00898     //drawing ylabel
00899     xt=padding/4.0;
00900     yt=height()/2.0;
00901     painter.save();
00902     painter.translate(xt,yt);
00903     painter.rotate(-90.0);
00904     painter.drawText(0,0,ylabel);
00905     painter.restore();
00906 
00907     
00908     /*
00909     painter.setPen(bluePen);
00910     painter.drawText(width()/2.0,padding/4.0*3,"Minimum");
00911     painter.setPen(greenPen);
00912     painter.drawText(width()/2.0,padding/4.0*2,"Average");
00913     painter.setPen(redPen);
00914     painter.drawText(width()/2.0,padding/4.0*1,"Maximum");
00915     */
00916     
00917     painter.setRenderHint(QPainter::Antialiasing, true);
00918     for (int dc=0;dc<nchunks;dc++)
00919     {
00920     int c=sortedIndex[dc];
00921     painter.setPen(dataChunks[c]->getColor());
00922     painter.drawText(width()-padding+2,padding+dc*20,dataChunks[c]->getLabel());
00923 
00924     for (int i=1;i<currentGen+1;i++)
00925     {
00926         /*
00927     painter.setPen(bluePen);
00928     painter.drawLine(padding+xstep*(i-1), height()-padding-getYnormValue(fitVal[i-1][0]),padding+xstep*i,height()-padding-getYnormValue(fitVal[i][0]));
00929     painter.setPen(greenPen);
00930     painter.drawLine(padding+xstep*(i-1), height()-padding-getYnormValue(fitVal[i-1][1]),padding+xstep*i,height()-padding-getYnormValue(fitVal[i][1]));
00931     painter.setPen(redPen);
00932     painter.drawLine(padding+xstep*(i-1), height()-padding-getYnormValue(fitVal[i-1][2]),padding+xstep*i,height()-padding-getYnormValue(fitVal[i][2]));
00933     */
00934     
00935     checkGraphRange(dataChunks[c]->getValue(i-1));
00936     painter.drawLine(padding+xstep*(i-1), height()-padding-getYnormValue(dataChunks[c]->getValue(i-1)),padding+xstep*i,height()-padding-getYnormValue(dataChunks[c]->getValue(i)));
00937     
00938 
00939     }
00940     }
00941 
00942 }
00943 
00944 double FitViewer::getYnormValue(double val)
00945 {
00946     if(vmin>0)
00947     {
00948     return (val/vmax)*wyaxes;
00949     }
00950     else
00951     {
00952 
00953     return ((val-vmin)/(vmax-vmin))*wyaxes;
00954     
00955     }
00956 }
00957 
00958 void FitViewer::setChunkLabel(int ch, const QString &label)
00959 {
00960 
00961     dataChunks[ch]->setLabel(label);
00962 }
00963 void FitViewer::setChunkProperties(int ch, const QString &label, QColor color, bool visible)
00964 {
00965     dataChunks[ch]->setLabel(label);
00966     dataChunks[ch]->setColor(color);
00967     dataChunks[ch]->setVisible(visible);
00968 }
00969 
00970 void FitViewer::setChunkValue(int ch,int ind, double value)
00971 {
00972     if (ch>= 0 && ch < this->nchunks)
00973     {
00974     dataChunks[ch]->setDataRaw(ind,value);  
00975     checkGraphRange(value);
00976     }
00977 }
00978 
00979 bool FitViewer::setChunkValue(const QString &name,int ind, double value)
00980 {
00981         for(int i=0;i<nchunks;i++)
00982     {
00983         if(name == dataChunks[i]->getLabel())
00984         {
00985             setChunkValue(i,ind, value);
00986             checkGraphRange(value);
00987             return true;
00988         }
00989     }
00990     return false;
00991 
00992 }
00993 void FitViewer::diplayUntilStep(int st)
00994 {
00995     currentGen=st;
00996 }
00997 
00998 void FitViewer::setLabels(const QString &title, const QString &xlabel, const QString &ylabel)
00999 {
01000     this->gtitle=title;
01001     this->xlabel=xlabel;
01002     this->ylabel=ylabel;
01003 }
01004 
01005 void FitViewer::reset()
01006 {
01007     vmin=-0.0;
01008     vmax=0.0;
01009     padding=90;
01010     setMinimumSize(padding*4,padding*4);
01011     currentGen=0;
01012 }
01013 
01014 bool FitViewer::loadRawData(int nchunk, const QString &filename, int column)
01015 {
01016     bool res;
01017     res=dataChunks[nchunk]->loadRawData(filename,column);
01018     if(res) 
01019     {
01020         //currentGen=dataChunks[nchunk]->getIndex()-1;
01021         if((dataChunks[nchunk]->getIndex()-1)>currentGen) currentGen=dataChunks[nchunk]->getIndex()-1;
01022     }
01023     checkChunkRange(nchunk);
01024     return res;
01025 }
01026 
01027 int FitViewer::getCurrentGeneration()
01028 {
01029     return currentGen;
01030 }
01031 
01032 void FitViewer::sortchunks()
01033 {
01034     bool swap=true;
01035     for(int i=0;i<nchunks;i++)
01036     {
01037         sortedIndex[i]=i;
01038     }
01039 
01040     while (swap)
01041     {
01042         swap=false;
01043         int s;
01044         for(int i=0;i<nchunks-1;i++)
01045         {
01046             if (dataChunks[sortedIndex[i]]->getMaxValue()<dataChunks[sortedIndex[i+1]]->getMaxValue())
01047             {
01048                 s=sortedIndex[i];
01049                 sortedIndex[i]=sortedIndex[i+1];
01050                 sortedIndex[i+1]=s;
01051                 swap=true;
01052             }
01053         }
01054     }
01055 }
01056 
01057 } //end namespace farsa