evonetui.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 "evonetui.h"
25 #include "displaycontroller.h"
26 #include "evodataviewer.h"
27 #include "holisticviewer.h"
28 #include "total99resources.h"
29 #include <QGridLayout>
30 #include <QPushButton>
31 #include <QCheckBox>
32 #include <QFileDialog>
33 #include <QVBoxLayout>
34 #include <QDir>
35 #include <QFileInfo>
36 #include <QFile>
37 #include <QEvent>
38 #include <QCoreApplication>
39 #include <QTimer>
40 #include <QElapsedTimer>
41 
42 // All the suff below is to avoid warnings on Windows about the use of unsafe
43 // functions. This should be only a temporary workaround, the solution is stop
44 // using C string and file functions...
45 #if defined(_MSC_VER)
46  #pragma warning(push)
47  #pragma warning(disable:4996)
48 #endif
49 
50 namespace farsa {
51 
53  : QObject()
55  , edv(NULL)
56  , hlv(NULL)
57  , networkDialog(NULL)
58  , evonet(net)
59  , neuronsMonitorDownloader( DataDownloader<ActivationsToGui>::NoNotification, neuronsMonitorUploader )
60  , nNeurons(0)
61 {
62  // Global connections
63  // !! DO NOT CONNECT TO THE evonetUpdated SIGNAL to update the network becuase that signals may be
64  // emitted so fast that the GUI will freeze !!
65  //connect( evonet, SIGNAL(evonetUpdated()), this, SLOT(onEvonetUpdated()), Qt::QueuedConnection );
66  QTimer* timer = new QTimer(this);
67  timer->setInterval( 40 );
68  timer->setSingleShot( false );
69  timer->start();
70  connect( timer, SIGNAL(timeout()), this, SLOT(onEvonetUpdated()) );
71 }
72 
74 {
75  // Nothing to do
76  // --- All objects are destroyed in others parts because none of them are owend by this object
77 }
78 
79 QList<ParameterSettableUIViewer> EvonetUI::getViewers( QWidget* parent, Qt::WindowFlags flags ) {
80  QList<ParameterSettableUIViewer> viewsList;
81  viewsList.append( networkView( parent, flags ) );
82  viewsList.append( neuroMonitorView( parent, flags ) );
83  viewsList.append( holisticView( parent, flags ) );
84  return viewsList;
85 }
86 
87 ParameterSettableUIViewer EvonetUI::networkView( QWidget* parent, Qt::WindowFlags flags )
88 {
89  networkDialog = new NetworkDialog(evonet,parent,flags);
90  networkDialog->pseudo_activate_net();
91  networkDialog->setWindowTitle( "Neural Network Editor" );
92  return ParameterSettableUIViewer( networkDialog, "Nervous System" );
93 }
94 
95 ParameterSettableUIViewer EvonetUI::neuroMonitorView( QWidget* parent, Qt::WindowFlags flags )
96 {
97  int addInfo = (evonet->showTeachingInput() ? evonet->getNoOutputs() + 1 : 0);
98  nNeurons = evonet->getNoNeurons();
99  edv = new EvoDataViewer( evonet->getNoNeurons() + addInfo, 1000, 0, parent, flags );
100 
101  //setting chunk properties
102  int i;
103  bool dn;
104  for (i = 0; i < evonet->getNoNeurons(); i++) {
105  if (evonet->neurondisplay[i] == 1) {
106  dn = true;
107  } else {
108  dn = false;
109  }
110  if ( evonet->neurondcolor[i].isValid() ) {
111  edv->setChunkProperties(i, evonet->neuronrange[i][0], evonet->neuronrange[i][1], evonet->neuronl[i], evonet->neurondcolor[i], dn);
112  } else {
113  // if the color is not valid, will use the color red
114  edv->setChunkProperties(i, evonet->neuronrange[i][0], evonet->neuronrange[i][1], evonet->neuronl[i], QColor(255,0,0), dn);
115  }
116  }
117  // Setting chunk properties for teaching input and backpropagation error (if the teaching input must be shown)
118  dn = true;
119  if (evonet->showTeachingInput())
120  {
121  for (i = 0; i < evonet->getNoOutputs(); i++)
122  {
123  edv->setChunkProperties(evonet->getNoNeurons() + i, 0.0, 1.0, "tInput[" + QString::number(i) + "]", QColor(255,0,0), dn);
124  }
125  edv->setChunkProperties(evonet->getNoNeurons() + evonet->getNoOutputs(), 0.0, 1.0, "error", QColor(255,0,0), dn);
126  }
127  //
128  edv->setWindowTitle( "Neurons Monitor" );
129  edv->setGeometry(50, 50, 600, 600);
130  return ParameterSettableUIViewer( edv, "Neurons Monitor" );
131 }
132 
133 ParameterSettableUIViewer EvonetUI::holisticView( QWidget* parent, Qt::WindowFlags flags )
134 {
135  hlv = new HolisticViewer(evonet, parent, flags);
136  hlv->resize(300, 300);
137  hlv->setWindowTitle("Holistic Viewer");
138  return ParameterSettableUIViewer( hlv, "Holistic View" );
139 }
140 
141 void EvonetUI::onEvonetUpdated() {
142  if ( edv ) {
143  QElapsedTimer timer;
144  timer.start();
145  while(true) {
146  // This call returns NULL if no new activation is available
147  const ActivationsToGui* d = neuronsMonitorDownloader.downloadDatum();
148 
149  if (d == NULL) {
150  break;
151  }
152 
153  if (d->activations) {
154  for (int ch = 0; ch < d->data.size(); ch++) {
155  edv->setChunkValue(ch, d->data[ch]);
156  }
157 
158  // Also setting the current step
159  edv->setCurrentStep(d->updatesCounter);
160  } else {
161  // Setting teaching inputs
162  for (int ch = 0; ch < (d->data.size() - 1); ch++) {
163  edv->setChunkValue(nNeurons + ch, d->data[ch]);
164  }
165  // The error is the last value in d->data
166  edv->setChunkValue(nNeurons + d->data.size() - 1, d->data.last());
167 
168 
169  // Also setting the current step
170  edv->setCurrentStep(d->updatesCounter);
171  }
172  // break the cycle if it takes too long to get data
173  if ( timer.elapsed() > 20 ) {
174  break;
175  }
176  }
177  edv->update();
178  }
179 
180  // updating the Newtork Dialog
181  if ( networkDialog ) {
182  networkDialog->update();
183  }
184  // updating holistic viewer
185  if ( hlv ) {
186  hlv->updateGrid();
187  hlv->updatePlot();
188  hlv->update();
189  }
190 }
191 
192 } //end namespace farsa
193 
194 // All the suff below is to restore the warning state on Windows
195 #if defined(_MSC_VER)
196  #pragma warning(pop)
197 #endif