Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

MonitorArea.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   SpikeStream Application                                               *
00003  *   Copyright (C) 2007 by David Gamez                                     *
00004  *   david@davidgamez.eu                                                   *
00005  *   Version 0.1                                                           *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************/
00022 
00023 //SpikeStream includes
00024 #include "MonitorArea.h"
00025 #include "Debug.h"
00026 #include "Utilities.h"
00027 #include "GlobalVariables.h"
00028 #include "SpikeStreamMainWindow.h"
00029 
00030 //Qt includes
00031 #include <qwidget.h>
00032 #include <qlayout.h>
00033 #include <qapplication.h>
00034 #include <qmessagebox.h>
00035 
00036 #include <mysql++.h>
00037 using namespace mysqlpp;
00038 
00039 
00040 /*! Constructor for live monitoring a simulation. */
00041 MonitorArea::MonitorArea(DBInterface *netDBInter, SimulationManager* simMan, QWidget *parent) : QDockArea(Qt::Vertical, QDockArea::Normal, parent, "Monitor Docking Area"){
00042         //This monitor area is being used to monitor a simulation
00043         simulationMode = true;
00044 
00045         //Store references
00046         networkDBInterface = netDBInter;
00047         simulationManager = simMan;
00048         spikeStrApp = SpikeStreamMainWindow::spikeStreamApplication;//Set up a short version of this reference
00049 
00050         //Set endPos to zero so that new windows are created at zero
00051         endPos = 0;
00052 
00053         //Initialise boolean variables
00054         firstTimeUndock = true;
00055 
00056         //Create MonitorWindows and add them to avoid problems dynamically adding qdockwindows
00057         monitorWindowArray = new MonitorWindow*[MAX_NUMBER_MONITOR_WINDOWS];
00058         for(int i=0; i < MAX_NUMBER_MONITOR_WINDOWS; ++i){
00059                 monitorWindowArray[i] = new MonitorWindow(simulationManager, this);
00060                 monitorWindowArray[i]->hide();
00061         }
00062 }
00063 
00064 
00065 /*! Constructor for when the monitor area is being used to play back an archive. */
00066 MonitorArea::MonitorArea(ArchiveManager *archMan, QWidget *parent) : QDockArea(Qt::Vertical, QDockArea::Normal, parent, "Monitor Docking Area"){
00067         //This monitor area is part of the archive widget       
00068         simulationMode = false;
00069 
00070         //Store references
00071         archiveManager = archMan;
00072         spikeStrApp = SpikeStreamMainWindow::spikeStreamApplication;//Set up a short version of this reference
00073 
00074         //Set endPos to zero so that new windows are created at zero
00075         endPos = 0;
00076 
00077         //Initialise boolean variables
00078         firstTimeUndock = true;
00079 
00080         //Create MonitorWindows and add them to avoid problems dynamically adding qdockwindows
00081         monitorWindowArray = new MonitorWindow*[MAX_NUMBER_MONITOR_WINDOWS];
00082         for(int i=0; i< MAX_NUMBER_MONITOR_WINDOWS; ++i){
00083                 monitorWindowArray[i] = new MonitorWindow(this);
00084                 monitorWindowArray[i]->hide();
00085         }
00086 }
00087 
00088 
00089 /*! Destructor. */
00090 MonitorArea::~MonitorArea(){
00091         #ifdef MEMORY_DEBUG
00092                 cout<<"DESTROYING MONITOR AREA"<<endl;
00093         #endif//MEMORY_DEBUG
00094 
00095         //Delete all existing network monitors
00096         /*for(map<unsigned int, NetworkMonitor*>::iterator iter = networkMonitorMap.begin(); iter != networkMonitorMap.end(); ++iter)
00097                 delete iter->second;*/
00098 
00099         //Delete monitor window array. The monitor windows should be deleted by Qt
00100         //FIXME THIS SEEMS TO CRASH SOMETIMES WHEN EXITING
00101         delete [] monitorWindowArray;
00102 }
00103 
00104 
00105 //-------------------------------------------------------------------------
00106 //------------------------- PUBLIC METHODS --------------------------------
00107 //-------------------------------------------------------------------------
00108 
00109 /*! Sets up network monitors and monitor windows ready for simulation monitoring or 
00110         archive playback. */
00111 void MonitorArea::addMonitorWindow(NeuronGroup neuronGrp){
00112         //Run a check that endPos has not been exceeded
00113         if(endPos >= MAX_NUMBER_MONITOR_WINDOWS){
00114                 cerr<<"MonitorArea: MAXIMUM NUMBER OF MONITOR WINDOWS HAS BEEN EXCEEDED. CANNOT ADD ANY MORE WINDOWS"<<endl;
00115                 return;
00116         }
00117 
00118         //Check that there is not a network monitor already for this neuron group
00119         if(networkMonitorMap.count(neuronGrp.neuronGrpID) > 0){
00120                 cerr<<"MonitorArea: NETWORK MONITOR ALREADY EXISTS FOR THIS NEURON GROUP!"<<endl;
00121                 return;
00122         }
00123 
00124         //Add the network monitor 
00125         if(simulationMode){
00126                 networkMonitorMap[neuronGrp.neuronGrpID] = new NetworkMonitor(neuronGrp, networkDBInterface, monitorWindowArray[endPos]);
00127                 monitorWindowArray[endPos]->setCaption(neuronGrp.name + " [" + QString::number(neuronGrp.neuronGrpID) + "]");
00128                 monitorWindowArray[endPos]->setNeuronGrpID(neuronGrp.neuronGrpID);
00129                 monitorWindowArray[endPos]->setWidget(networkMonitorMap[neuronGrp.neuronGrpID]);
00130         }
00131         else{//Archive mode
00132                 networkMonitorMap[neuronGrp.neuronGrpID] = new NetworkMonitor(neuronGrp, monitorWindowArray[endPos]);
00133                 monitorWindowArray[endPos]->setCaption(neuronGrp.name + " [" + QString::number(neuronGrp.neuronGrpID) + "]");
00134                 monitorWindowArray[endPos]->setWidget(networkMonitorMap[neuronGrp.neuronGrpID]);
00135                 monitorWindowArray[endPos]->show();
00136         }
00137 
00138         /* Increase the record of the position to add in the array */
00139         ++endPos;
00140 }
00141 
00142 
00143 /*! Called at the start of a simulation or archive playback
00144         to set the network monitors in the      manager. 
00145         This enables the network monitors to be directly updated from the manager. */
00146 void MonitorArea::connectToManager(){
00147         if(simulationMode)
00148                 simulationManager->setNetworkMonitors(networkMonitorMap);
00149         else
00150                 archiveManager->setNetworkMonitors(networkMonitorMap);
00151 }
00152 
00153 
00154 /*! Docks all monitor windows. */
00155 void MonitorArea::dockMonitorWindows(){
00156         for(int i=0; i<endPos; ++i){
00157                 if(!monitorWindowArray[i]->isHidden() && (monitorWindowArray[i]->place() == QDockWindow::OutsideDock))//Check to see if it is hidden or not
00158                         monitorWindowArray[i]->dock();
00159         }
00160 }
00161 
00162 
00163 /*! Hides all monitor windows. */
00164 void MonitorArea::hideMonitorWindows(){
00165         for(int i=0; i<endPos; ++i){
00166                 monitorWindowArray[i]->hide();
00167         }
00168 }
00169 
00170 
00171 /*! Loads up the network monitors and adds them to the window ready to be hidden or
00172         shown during the simulation. */
00173 void MonitorArea::loadSimulation(){
00174         //Get a list of neuron group IDs along with their width and length
00175         try{
00176                 Query query = networkDBInterface->getQuery();
00177                 query.reset();
00178                 query<<"SELECT NeuronGrpID, Name, Width, Length FROM NeuronGroups";
00179                 Result result = query.store();
00180                 for(Result::iterator iter = result.begin(); iter != result.end(); ++iter){
00181                         Row neurGrpRow(*iter);
00182                         
00183                         //Extract parameters of neuron group from database
00184                         NeuronGroup neuronGrp;
00185                         neuronGrp.width = Utilities::getUInt((std::string)neurGrpRow["Width"]);
00186                         neuronGrp.length = Utilities::getUInt((std::string)neurGrpRow["Length"]);
00187                         neuronGrp.neuronGrpID = Utilities::getUInt((std::string)neurGrpRow["NeuronGrpID"]);
00188                         neuronGrp.name = (std::string)neurGrpRow["Name"];
00189                 
00190                         //Add a dock window and network monitor
00191                         addMonitorWindow(neuronGrp);
00192                 }
00193         }
00194         catch (const BadQuery& er) {// Handle any query errors
00195                 cerr<<"MonitorArea: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00196                 QString errorString = "Bad query loading neuron group: \"";
00197                 errorString += er.what();
00198                 errorString += "\"";
00199                 QMessageBox::critical( 0, "Neuron Group Error", errorString);
00200         }
00201         catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00202                 cerr<<"MonitorArea: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00203                 QString errorString = "Exception thrown loading neuron group: \"";
00204                 errorString += er.what();
00205                 errorString += "\"";
00206                 QMessageBox::critical( 0, "Neuron Group Error", errorString);
00207         }
00208         catch(std::exception& er){// Catch-all for std exceptions
00209                 cerr<<"MonitorArea: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00210                 QString errorString = "Exception thrown loading neuron group: \"";
00211                 errorString += er.what();
00212                 errorString += "\"";
00213                 QMessageBox::critical( 0, "Neuron Group Error", errorString);
00214         }
00215 }
00216 
00217 
00218 /*! Resets the monitor windows. */
00219 void MonitorArea::resetMonitorWindows(){
00220         //Hide all monitor windows
00221         hideMonitorWindows();
00222 
00223         //reset insertion position
00224         endPos = 0;
00225         
00226         //Delete all existing network monitors
00227         for(map<unsigned int, NetworkMonitor*>::iterator iter = networkMonitorMap.begin(); iter != networkMonitorMap.end(); ++iter)
00228                 delete iter->second;
00229         networkMonitorMap.clear();
00230 }
00231 
00232 
00233 /*! Rewinds network monitors back to zero time step. */
00234 void MonitorArea::rewindNetworkMonitors(){
00235         for(map<unsigned int, NetworkMonitor*>::iterator iter = networkMonitorMap.begin(); iter != networkMonitorMap.end(); ++iter)
00236                 iter->second->reset();
00237 }
00238 
00239 
00240 /*! Shows all monitor windows. */
00241 void MonitorArea::showAllMonitorWindows(bool monitorNeurons){
00242         for(int i=0; i<endPos; ++i){
00243                 monitorWindowArray[i]->setMonitorType(monitorNeurons);
00244                 monitorWindowArray[i]->show();
00245         }
00246 }
00247 
00248 
00249 /*! Displays the monitor window with the neuron grp id. Linear search is a bit slow,
00250         This could be speeded up by using a map to store the link between a position in the
00251         array and the neuronGrpID, but it may not be necessary since it is not a frequent operation. */
00252 void MonitorArea::showMonitorWindow(unsigned int neurGrpID, bool monitorNeurons){
00253         for(int i=0; i<endPos; ++i){
00254                 if(monitorWindowArray[i]->getNeuronGrpID() == neurGrpID){
00255                         monitorWindowArray[i]->setMonitorType(monitorNeurons);
00256                         monitorWindowArray[i]->show();
00257                         return;
00258                 }
00259         }
00260 }
00261 
00262 
00263 /*! Undocks the monitor windows and lays them out within the window if this can be done
00264         easily. This is only done for the first undocking action since after this the 
00265         user is presumed to have arranged the windows to their preference. */
00266 void MonitorArea::undockMonitorWindows(){
00267         int deskTopWidth = QApplication::desktop()->width();
00268         int deskTopHeight = QApplication::desktop()->height();
00269         int numWindowsInSpace = deskTopWidth / 100;//This is 2 x the width / the width of the current windows (200)
00270         int currentXPos = 0;
00271         int currentYPos = 0;
00272 
00273         for(int i=0; i<endPos; ++i){
00274                 if(!monitorWindowArray[i]->isHidden()){//Check to see if it is hidden or not
00275                         monitorWindowArray[i]->undock();
00276 
00277                         /* Arrange across the top two lines of the desktop if there is space
00278                                 Only do this if there is two rows or less of monitor windows */
00279                         if(firstTimeUndock && i < numWindowsInSpace ){
00280                                 monitorWindowArray[i]->move(currentXPos, currentYPos);
00281                                 currentXPos += 200;
00282                                 if(currentXPos >= (deskTopWidth - 150)){//Don't want window to be more than 50 pixels off screen
00283                                         currentXPos = 0;
00284                                         currentYPos += 200;
00285                                 }
00286                         }
00287                         else if(firstTimeUndock){//Stack up windows in bottom right corner
00288                                 monitorWindowArray[i]->move(deskTopWidth - 210, deskTopHeight - 200 - i * 10);
00289                         }
00290                 }
00291         }
00292         firstTimeUndock = false;
00293 }
00294 
00295 

Generated on Mon Sep 3 22:29:04 2007 for SpikeStream Application by  doxygen 1.4.4