SpikeStream Nemo Plugin  0.2
NemoWidget.cpp
Go to the documentation of this file.
00001 //SpikeStream includes
00002 #include "DeviceLoaderWidget.h"
00003 #include "ExperimentLoaderWidget.h"
00004 #include "Globals.h"
00005 #include "GlobalVariables.h"
00006 #include "NemoParametersDialog.h"
00007 #include "NemoWidget.h"
00008 #include "NeuronParametersDialog.h"
00009 #include "NeuronGroupSelectionDialog.h"
00010 #include "Pattern.h"
00011 #include "PatternManager.h"
00012 #include "SpikeStreamSimulationException.h"
00013 #include "SynapseParametersDialog.h"
00014 #include "Util.h"
00015 using namespace spikestream;
00016 
00017 //Qt includes
00018 #include <QButtonGroup>
00019 #include <QDebug>
00020 #include <QFileDialog>
00021 #include <QLayout>
00022 #include <QMessageBox>
00023 #include <QMutexLocker>
00024 
00026 #define LOAD_PATTERN_STRING "Load Pattern"
00027 
00028 #define MONITOR_NEURONS_OFF 0
00029 #define MONITOR_NEURONS_FIRING 1
00030 #define MONITOR_NEURONS_MEMBRANE 2
00031 
00032 
00033 //Functions for dynamic library loading
00034 extern "C" {
00036         QWidget* getClass(){
00037                 return new NemoWidget();
00038         }
00039 
00041         QString getName(){
00042                 return QString("NeMo CUDA Simulator");
00043         }
00044 }
00045 
00046 
00048 NemoWidget::NemoWidget(QWidget* parent) : QWidget(parent) {
00049         //Register types to enable signals and slots to work
00050         qRegisterMetaType< QList<unsigned> >("QList<unsigned>");
00051         qRegisterMetaType< QHash<unsigned, float> >("QHash<unsigned, float>");
00052 
00053         //Create colours to be used for membrane potential
00054         createMembranePotentialColors();
00055 
00056         //Create layout for the entire widget
00057         QVBoxLayout* mainVBox = new QVBoxLayout(this);
00058         mainGroupBox = new QGroupBox("Nemo CUDA Simulator", this);
00059         controlsWidget = new QWidget();
00060         controlsWidget->setEnabled(false);
00061         QVBoxLayout* controlsVBox = new QVBoxLayout(controlsWidget);
00062 
00063         //Add load, unload and parameters buttons
00064         loadButton = new QPushButton("Load");
00065         connect(loadButton, SIGNAL(clicked()), this, SLOT(loadSimulation()));
00066         unloadButton = new QPushButton("Unload");
00067         connect(unloadButton, SIGNAL(clicked()), this, SLOT(unloadSimulation()));
00068         unloadButton->setEnabled(false);
00069         neuronParametersButton = new QPushButton(" Neuron Parameters ");
00070         connect(neuronParametersButton, SIGNAL(clicked()), this, SLOT(setNeuronParameters()));
00071         synapseParametersButton = new QPushButton(" Synapse Parameters ");
00072         connect(synapseParametersButton, SIGNAL(clicked()), this, SLOT(setSynapseParameters()));
00073         nemoParametersButton = new QPushButton(" NeMo Parameters ");
00074         connect(nemoParametersButton, SIGNAL(clicked()), this, SLOT(setNemoParameters()));
00075         QHBoxLayout* loadLayout = new QHBoxLayout();
00076         loadLayout->addWidget(loadButton);
00077         loadLayout->addWidget(unloadButton);
00078         loadLayout->addWidget(neuronParametersButton);
00079         loadLayout->addWidget(synapseParametersButton);
00080         loadLayout->addWidget(nemoParametersButton);
00081         mainVBox->addLayout(loadLayout);
00082 
00083         //Add the tool bar
00084         toolBar = getToolBar();
00085         controlsVBox->addWidget(toolBar);
00086 
00087         //Group box for monitoring controls
00088         monitorGroupBox = new QGroupBox("Monitor", controlsWidget);
00089         QVBoxLayout* monitorVBox = new QVBoxLayout();
00090 
00091         //Add widget to control live monitoring of neurons
00092         QHBoxLayout* monitorNeuronsBox = new QHBoxLayout();
00093         monitorNeuronsBox->addWidget(new QLabel("Monitor neurons: "));
00094         QButtonGroup* monitorNeuronsButtonGroup = new QButtonGroup();
00095         connect(monitorNeuronsButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(monitorNeuronsStateChanged(int)));
00096         noMonitorNeuronsButton = new QRadioButton("Off");
00097         noMonitorNeuronsButton->setChecked(true);
00098         monitorNeuronsButtonGroup->addButton(noMonitorNeuronsButton, MONITOR_NEURONS_OFF);
00099         monitorNeuronsBox->addWidget(noMonitorNeuronsButton);
00100         monitorFiringNeuronsButton = new QRadioButton("Firing");
00101         monitorNeuronsButtonGroup->addButton(monitorFiringNeuronsButton, MONITOR_NEURONS_FIRING);
00102         monitorNeuronsBox->addWidget(monitorFiringNeuronsButton);
00103         rasterButton = new QPushButton("Raster");
00104         connect(rasterButton, SIGNAL(clicked()), this, SLOT(rasterButtonClicked()));
00105         rasterButton->setMaximumSize(60,20);
00106         rasterButton->setEnabled(false);
00107         monitorNeuronsBox->addWidget(rasterButton);
00108         monitorMemPotNeuronsButton = new QRadioButton("Membrane potential");
00109         monitorNeuronsButtonGroup->addButton(monitorMemPotNeuronsButton, MONITOR_NEURONS_MEMBRANE);
00110         monitorNeuronsBox->addWidget(monitorMemPotNeuronsButton);
00111         memPotGraphButton = new QPushButton("Graph");
00112         connect(memPotGraphButton, SIGNAL(clicked()), this, SLOT(memPotGraphButtonClicked()));
00113         memPotGraphButton->setMaximumSize(60,20);
00114         memPotGraphButton->setEnabled(false);
00115         monitorNeuronsBox->addWidget(memPotGraphButton);
00116         monitorNeuronsBox->addStretch(5);
00117         monitorVBox->addLayout(monitorNeuronsBox);
00118         monitorVBox->addSpacing(5);
00119 
00120         //Add widgets to monitor, save and reset the weights
00121         QHBoxLayout* saveWeightsBox = new QHBoxLayout();
00122         monitorWeightsCheckBox = new QCheckBox("Monitor weights");
00123         connect(monitorWeightsCheckBox, SIGNAL(clicked(bool)), this, SLOT(setMonitorWeights(bool)));
00124         saveWeightsBox->addWidget(monitorWeightsCheckBox);
00125 /*      resetWeightsButton = new QPushButton("Reset Weights");
00126         connect(resetWeightsButton, SIGNAL(clicked()), this, SLOT(resetWeights()));
00127         saveWeightsBox->addWidget(resetWeightsButton);*/
00128         saveWeightsButton = new QPushButton("Save Weights");
00129         connect(saveWeightsButton, SIGNAL(clicked()), this, SLOT(saveWeights()));
00130         saveWeightsBox->addWidget(saveWeightsButton);
00131         saveWeightsBox->addStretch(5);
00132         monitorVBox->addLayout(saveWeightsBox);
00133 
00134         //Add widgets to control archiving
00135         archiveCheckBox = new QCheckBox("Archive.");
00136         connect(archiveCheckBox, SIGNAL(stateChanged(int)), this, SLOT(archiveStateChanged(int)));
00137         archiveDescriptionEdit = new QLineEdit("Undescribed");
00138         archiveDescriptionEdit->setEnabled(false);
00139         setArchiveDescriptionButton = new QPushButton("Set Description");
00140         setArchiveDescriptionButton->setEnabled(false);
00141         connect(setArchiveDescriptionButton, SIGNAL(clicked()), this, SLOT(setArchiveDescription()));
00142         QHBoxLayout* archiveLayout = new QHBoxLayout();
00143         archiveLayout->addWidget(archiveCheckBox);
00144         archiveLayout->addWidget(archiveDescriptionEdit);
00145         archiveLayout->addWidget(setArchiveDescriptionButton);
00146         monitorVBox->addLayout(archiveLayout);
00147 
00148         //Add monitor group box to layout
00149         monitorGroupBox->setLayout(monitorVBox);
00150         controlsVBox->addWidget(monitorGroupBox);
00151 
00152         //Group box for injection controls
00153         injectGroupBox = new QGroupBox("Inject", controlsWidget);
00154         QVBoxLayout* injectVBox = new QVBoxLayout();
00155 
00156 
00157         //Add widgets to inject noise into specified layers
00158         QHBoxLayout* injectNoiseBox = new QHBoxLayout();
00159         injectNoiseNeuronGroupCombo = new QComboBox();
00160         injectNoiseNeuronGroupCombo->setMinimumSize(200, 20);
00161         injectNoiseBox->addWidget(injectNoiseNeuronGroupCombo);
00162         injectNoisePercentCombo = new QComboBox();
00163         injectNoisePercentCombo->addItem("0.1 %");
00164         injectNoisePercentCombo->addItem("1 %");
00165         for(int i=10; i<=100; i += 10)
00166                 injectNoisePercentCombo->addItem(QString::number(i) + " %");
00167         injectNoisePercentCombo->setMinimumSize(60, 20);
00168         injectNoiseBox->addWidget(injectNoisePercentCombo);
00169 
00170         injectNoiseCurrentCombo = new QComboBox();
00171         injectNoiseCurrentCombo->addItem("Fire");
00172         injectNoiseCurrentCombo->addItem("1");
00173         for(int i=10; i<=100; i += 10)
00174                 injectNoiseCurrentCombo->addItem(QString::number(i));
00175         injectNoiseCurrentCombo->setMinimumSize(60, 20);
00176         injectNoiseBox->addWidget(injectNoiseCurrentCombo);
00177 
00178         injectNoiseButton = new QPushButton("Inject Noise");
00179         injectNoiseButton->setMinimumHeight(20);
00180         connect(injectNoiseButton, SIGNAL(clicked()), this, SLOT(injectNoiseButtonClicked()));
00181         injectNoiseBox->addWidget(injectNoiseButton);
00182         sustainNoiseChkBox = new QCheckBox("Sustain");
00183         connect(sustainNoiseChkBox, SIGNAL(clicked(bool)), this, SLOT(sustainNoiseChanged(bool)));
00184         injectNoiseBox->addWidget(sustainNoiseChkBox);
00185         injectNoiseBox->addStretch(5);
00186         injectVBox->addSpacing(5);
00187         injectVBox->addLayout(injectNoiseBox);
00188 
00189         //Add widgets to enable injection of patterns
00190         QHBoxLayout* injectPatternBox = new QHBoxLayout();
00191         injectPatternNeurGrpCombo = new QComboBox();
00192         injectPatternNeurGrpCombo->setMinimumSize(200, 20);
00193         injectPatternBox->addWidget(injectPatternNeurGrpCombo);
00194         patternCombo = new QComboBox();
00195         patternCombo->setMinimumSize(200, 20);
00196         patternCombo->addItem("");
00197         patternCombo->addItem(LOAD_PATTERN_STRING);
00198         connect(patternCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(loadPattern(QString)));
00199         patternCurrentCombo = new QComboBox();
00200         fillPatternCurrentCombo();
00201         injectPatternBox->addWidget(patternCurrentCombo);
00202         injectPatternBox->addWidget(patternCombo);
00203         injectPatternButton = new QPushButton("Inject Pattern");
00204         injectPatternButton->setEnabled(false);
00205         injectPatternButton->setMinimumHeight(22);
00206         connect(injectPatternButton, SIGNAL(clicked()), this, SLOT(injectPatternButtonClicked()));
00207         injectPatternBox->addWidget(injectPatternButton);
00208         sustainPatternChkBox = new QCheckBox("Sustain");
00209         sustainPatternChkBox->setEnabled(false);
00210         connect(sustainPatternChkBox, SIGNAL(clicked(bool)), this, SLOT(sustainPatternChanged(bool)));
00211         injectPatternBox->addWidget(sustainPatternChkBox);
00212         injectVBox->addSpacing(5);
00213         injectVBox->addLayout(injectPatternBox);
00214 
00215         //Add inject group box to layout
00216         injectGroupBox->setLayout(injectVBox);
00217         controlsVBox->addWidget(injectGroupBox);
00218 
00219         //Group box for plugins, such as experiments and devices
00220         QGroupBox* pluginsGroupBox = new QGroupBox("Plugins", controlsWidget);
00221         QVBoxLayout* pluginsVBox = new QVBoxLayout();
00222         QTabWidget* pluginsTabWidget = new QTabWidget();
00223 
00224         //Add widget that loads devices
00225         DeviceLoaderWidget* deviceLoaderWidget = new DeviceLoaderWidget(Globals::getSpikeStreamRoot() + "/plugins/simulation/nemodevices");
00226         deviceLoaderWidget->setMinimumSize(600, 200);
00227         pluginsTabWidget->addTab(deviceLoaderWidget, "Devices");
00228 
00229         //Add widget that loads experiments
00230         ExperimentLoaderWidget* exptLoaderWidget = new ExperimentLoaderWidget(Globals::getSpikeStreamRoot() + "/plugins/simulation/nemoexperiments");
00231         exptLoaderWidget->setMinimumSize(600, 200);
00232         pluginsTabWidget->addTab(exptLoaderWidget, "Experiments");
00233 
00234         //Add experiment group box to layout
00235         pluginsVBox->addWidget(pluginsTabWidget);
00236         pluginsGroupBox->setLayout(pluginsVBox);
00237         controlsVBox->addWidget(pluginsGroupBox);
00238 
00239         //Put layout into enclosing box
00240         mainVBox->addWidget(controlsWidget);
00241         mainGroupBox->setLayout(mainVBox);
00242         this->setMinimumSize(800, 800);
00243 
00244         //Create wrapper for Nemo library
00245         nemoWrapper = new NemoWrapper();
00246         connect(nemoWrapper, SIGNAL(finished()), this, SLOT(nemoWrapperFinished()));
00247         connect(nemoWrapper, SIGNAL(progress(int,int)), this, SLOT(updateProgress(int, int)), Qt::QueuedConnection);
00248         connect(nemoWrapper, SIGNAL(simulationStopped()), this, SLOT(simulationStopped()), Qt::QueuedConnection);
00249         connect(nemoWrapper, SIGNAL(timeStepChanged(unsigned)), this, SLOT(updateTimeStep(unsigned)), Qt::QueuedConnection);
00250         connect(nemoWrapper, SIGNAL(timeStepChanged(unsigned, const QList<unsigned>&)), this, SLOT(updateTimeStep(unsigned, const QList<unsigned>&)), Qt::QueuedConnection);
00251         connect(nemoWrapper, SIGNAL(timeStepChanged(unsigned, const QHash<unsigned, float>&)), this, SLOT(updateTimeStep(unsigned, const QHash<unsigned, float>&)), Qt::QueuedConnection);
00252 
00253         //Pass device managers to NeMo wrapper
00254         QList<AbstractDeviceWidget*> deviceWidgetList = deviceLoaderWidget->getAbstractDeviceWidgets();
00255         foreach(AbstractDeviceWidget* tmpDevWidget, deviceWidgetList){
00256                 nemoWrapper->addDeviceManager(tmpDevWidget->getDeviceManager());
00257         }
00258 
00259         //Set up link between experiment widgets and NeMo wrapper and signals/slots
00260         QList<AbstractExperimentWidget*> exptWidgetList = exptLoaderWidget->getAbstractExperimentWidgets();
00261         foreach(AbstractExperimentWidget* tmpExptWidget, exptWidgetList){
00262                 tmpExptWidget->setWrapper(nemoWrapper);
00263                 connect(tmpExptWidget, SIGNAL(experimentStarted()), this, SLOT(experimentStarted()));
00264                 connect(tmpExptWidget, SIGNAL(experimentEnded()), this, SLOT(experimentEnded()));
00265         }
00266 
00267         //Listen for network changes
00268         connect(Globals::getEventRouter(), SIGNAL(networkChangedSignal()), this, SLOT(networkChanged()));
00269 
00270         //Listen for simulation control events
00271         connect(Globals::getEventRouter(), SIGNAL(startStopSimulationSignal()), this, SLOT(startStopSimulation()));
00272         connect(Globals::getEventRouter(), SIGNAL(stepSimulationSignal()), this, SLOT(stepSimulation()));
00273 
00274         //Set initial state of tool bar
00275         checkWidgetEnabled();
00276 
00277         //Initialise variables
00278         progressDialog = NULL;
00279         rasterDialogCtr = 0;
00280 }
00281 
00282 
00284 NemoWidget::~NemoWidget(){
00285         delete nemoWrapper;
00286         for(QHash<int, RGBColor*>::iterator iter = heatColorMap.begin(); iter != heatColorMap.end(); ++iter)
00287                 delete iter.value();
00288         heatColorMap.clear();
00289 }
00290 
00291 
00292 /*----------------------------------------------------------*/
00293 /*------                PRIVATE SLOTS                 ------*/
00294 /*----------------------------------------------------------*/
00295 
00297 void NemoWidget::archiveStateChanged(int state){
00298         if(state == Qt::Checked){
00299                 archiveDescriptionEdit->setEnabled(true);
00300                 setArchiveDescriptionButton->setEnabled(true);
00301                 if(archiveDescriptionEdit->text().isEmpty())
00302                         archiveDescriptionEdit->setText("Undescribed");
00303                 nemoWrapper->setArchiveMode(true, archiveDescriptionEdit->text());
00304         }
00305         else{
00306                 archiveDescriptionEdit->setEnabled(false);
00307                 setArchiveDescriptionButton->setEnabled(false);
00308                 nemoWrapper->setArchiveMode(false);
00309         }
00310 }
00311 
00312 
00316 void NemoWidget::checkLoadingProgress(){
00317         //Check for errors during loading
00318         if(nemoWrapper->isError()){
00319                 loadingTimer->stop();
00320                 progressDialog->setValue(progressDialog->maximum());
00321                 delete progressDialog;
00322                 progressDialog = NULL;
00323                 qCritical()<<"Error occurred loading simulation: '"<<nemoWrapper->getErrorMessage()<<"'.";
00324                 return;
00325         }
00326 
00327         //Check for cancelation - stop timer and abort operation
00328         else if(progressDialog->wasCanceled()){
00329                 loadingTimer->stop();
00330                 nemoWrapper->cancelLoading();
00331                 delete progressDialog;
00332                 progressDialog = NULL;
00333                 return;
00334         }
00335 
00336         //If simulation has not been loaded return with loading timer still running
00337         else if(!nemoWrapper->isSimulationLoaded()){
00338                 return;
00339         }
00340 
00341         else if (updatingProgress){
00342                 return;
00343         }
00344 
00345         //If we have reached this point, loading is complete
00346         loadingTimer->stop();
00347         progressDialog->setValue(progressDialog->maximum());
00348         delete progressDialog;
00349         progressDialog = NULL;
00350 
00351         //Adjust buttons
00352         loadButton->setEnabled(false);
00353         unloadButton->setEnabled(true);
00354         synapseParametersButton->setEnabled(false);
00355         nemoParametersButton->setEnabled(false);
00356         controlsWidget->setEnabled(true);
00357         playAction->setEnabled(true);
00358         stopAction->setEnabled(false);
00359         stepAction->setEnabled(true);
00360         monitorWeightsCheckBox->setChecked(nemoWrapper->isMonitorWeights());
00361         archiveCheckBox->setChecked(false);//Single archive associated with each simulation run
00362 
00363         //Cannot save weights or archive if the network is not fully saved in the database
00364         if(!Globals::getNetwork()->isSaved()){
00365                 archiveCheckBox->setEnabled(false);
00366                 setArchiveDescriptionButton->setEnabled(false);
00367                 archiveDescriptionEdit->setEnabled(false);
00368         }
00369         else{
00370                 archiveCheckBox->setEnabled(true);
00371                 setArchiveDescriptionButton->setEnabled(true);
00372                 archiveDescriptionEdit->setEnabled(true);
00373         }
00374 
00375         //Set nemo wrapper as the simulation in global scope
00376         Globals::setSimulation(nemoWrapper);
00377 }
00378 
00379 
00381 void NemoWidget::checkResetWeightsProgress(){
00382         //Check for errors during resetting weights
00383         if(nemoWrapper->isError()){
00384                 heavyTaskTimer->stop();
00385                 progressDialog->setValue(progressDialog->maximum());
00386                 delete progressDialog;
00387                 progressDialog = NULL;
00388                 qCritical()<<"Error occurred resetting of weights: '"<<nemoWrapper->getErrorMessage()<<"'.";
00389                 return;
00390         }
00391 
00392         //Check for cancelation - stop timer and abort operation
00393         else if(progressDialog->wasCanceled()){
00394                 heavyTaskTimer->stop();
00395                 nemoWrapper->cancelResetWeights();
00396                 delete progressDialog;
00397                 progressDialog = NULL;
00398                 return;
00399         }
00400 
00401         //If save weights is not complete return with timer running
00402         else if(!nemoWrapper->isWeightsReset()){
00403                 return;
00404         }
00405 
00406         else if (updatingProgress){
00407                 return;
00408         }
00409 
00410         //If we have reached this point, loading is complete
00411         heavyTaskTimer->stop();
00412         progressDialog->setValue(progressDialog->maximum());
00413         delete progressDialog;
00414         progressDialog = NULL;
00415 }
00416 
00417 
00419 void NemoWidget::checkSaveWeightsProgress(){
00420         //Check for errors during loading
00421         if(nemoWrapper->isError()){
00422                 heavyTaskTimer->stop();
00423                 progressDialog->setValue(progressDialog->maximum());
00424                 delete progressDialog;
00425                 progressDialog = NULL;
00426                 qCritical()<<"Error occurred saving of weights: '"<<nemoWrapper->getErrorMessage()<<"'.";
00427                 return;
00428         }
00429 
00430         //Check for cancelation - stop timer and abort operation
00431         else if(progressDialog->wasCanceled()){
00432                 heavyTaskTimer->stop();
00433                 nemoWrapper->cancelSaveWeights();
00434                 delete progressDialog;
00435                 progressDialog = NULL;
00436                 return;
00437         }
00438 
00439         //If simulation has not been loaded return with loading timer still running
00440         else if(!nemoWrapper->isWeightsSaved()){
00441                 return;
00442         }
00443 
00444         //Make sure that progress dialog is not being redrawn
00445         else if (updatingProgress){
00446                 return;
00447         }
00448 
00449         //If we have reached this point, loading is complete
00450         heavyTaskTimer->stop();
00451         progressDialog->setValue(progressDialog->maximum());
00452         delete progressDialog;
00453         progressDialog = NULL;
00454 }
00455 
00456 
00459 void NemoWidget::deleteMembranePotentialGraphDialog(int){
00460         unsigned tmpID = sender()->objectName().toUInt();
00461         qDebug()<<"Deleting Membrane potential graph dialog with ID: "<<tmpID;
00462         if(!memPotGraphDialogMap.contains(tmpID)){
00463                 qCritical()<<"Raster dialog not found: ID="<<tmpID;
00464                 return;
00465         }
00466         memPotGraphDialogMap.remove(tmpID);
00467 }
00468 
00469 
00472 void NemoWidget::deleteRasterPlotDialog(int){
00473         unsigned tmpID = sender()->objectName().toUInt();
00474         qDebug()<<"Deleting Raster plot dialog with ID: "<<tmpID;
00475         if(!rasterDialogMap.contains(tmpID))
00476                 throw SpikeStreamException("Raster dialog not found: ID=" + QString::number(tmpID));
00477         //delete rasterDialogMap[tmpID];
00478         rasterDialogMap.remove(tmpID);
00479 }
00480 
00481 
00483 void NemoWidget::experimentEnded(){
00484         toolBar->setEnabled(true);
00485         monitorGroupBox->setEnabled(true);
00486         injectGroupBox->setEnabled(true);
00487 }
00488 
00489 
00491 void NemoWidget::experimentStarted(){
00492         toolBar->setEnabled(false);
00493         monitorGroupBox->setEnabled(false);
00494         injectGroupBox->setEnabled(false);
00495 }
00496 
00497 
00500 void NemoWidget::injectNoiseButtonClicked(){
00501         setInjectNoise(false);
00502 }
00503 
00504 
00507 void NemoWidget::injectPatternButtonClicked(){
00508         setInjectionPattern(false);
00509 }
00510 
00511 
00514 void NemoWidget::loadPattern(QString comboStr){
00515         //Return if we are setting the pattern to another pattern.
00516         if(comboStr != LOAD_PATTERN_STRING){
00517                 return;
00518         }
00519 
00520         //Reset pattern combo
00521         patternCombo->setCurrentIndex(0);
00522 
00523         //Select file containing new pattern.
00524         QString filePath = getFilePath("*.pat");
00525         if(filePath.isEmpty())
00526                 return;
00527         if(!QFile::exists(filePath)){
00528                 qCritical()<<"Selected file '"<<filePath<<"' does not exist.";
00529                 return;
00530         }
00531 
00532         try{
00533                 //Load up the new pattern
00534                 Pattern newPattern;
00535                 PatternManager::load(filePath, newPattern);
00536 
00537                 //Add name to combo if it does not already exist
00538                 if(!patternMap.contains(filePath)){
00539                         patternCombo->insertItem(patternCombo->count() - 1, newPattern.getName());
00540                 }
00541 
00542                 //Replace pattern stored for this name with new pattern or add it if it doesn't exist.
00543                 patternMap[filePath] = newPattern;
00544 
00545                 //Set combo to display loaded item
00546                 if(patternCombo->itemText(0) == "")
00547                         patternCombo->removeItem(0);
00548                 patternCombo->setCurrentIndex(patternCombo->count() - 2);
00549 
00550                 //Enable injection and sustain buttons
00551                 injectPatternButton->setEnabled(true);
00552                 sustainPatternChkBox->setEnabled(true);
00553         }
00554         catch(SpikeStreamException* ex){
00555                 qCritical()<<ex->getMessage();
00556         }
00557 }
00558 
00559 
00561 void NemoWidget::loadSimulation(){
00562         //Run some checks
00563         if(!Globals::networkLoaded()){
00564                 qCritical()<<"Cannot load simulation: no network loaded.";
00565                 return;
00566         }
00567         if(nemoWrapper->isRunning()){
00568                 qCritical()<<"Nemo wrapper is already running - cannot load simulation.";
00569                 return;
00570         }
00571         if(nemoWrapper->isSimulationLoaded()){
00572                 qCritical()<<"Simulation is already loaded - you must unload the current simulation before loading another.";
00573                 return;
00574         }
00575 
00576         //Load the current neuron groups into control widgets
00577         loadNeuronGroups();
00578 
00579         try{
00580                 //Store the current neuron colour for monitoring
00581                 neuronColor = Globals::getNetworkDisplay()->getSimulationFiringNeuronColor();
00582 
00583                 //Start loading of simulation
00584                 taskCancelled = false;
00585                 progressDialog = new QProgressDialog("Loading simulation", "Cancel", 0, 100, this, Qt::CustomizeWindowHint);
00586                 progressDialog->setWindowModality(Qt::WindowModal);
00587                 progressDialog->show();
00588                 updatingProgress = false;
00589                 nemoWrapper->start();//Load carried out by run method
00590 
00591                 //Wait for loading to finish and update progress dialog
00592                 loadingTimer  = new QTimer(this);
00593                 connect(loadingTimer, SIGNAL(timeout()), this, SLOT(checkLoadingProgress()));
00594                 loadingTimer->start(200);
00595         }
00596         catch(SpikeStreamException& ex){
00597                 qCritical()<<ex.getMessage();
00598         }
00599 }
00600 
00601 
00602 
00605 void NemoWidget::memPotGraphButtonClicked(){
00606         //Get ID of current neuron
00607         neurid_t neurID = Globals::getNetworkDisplay()->getSingleNeuronID();
00608         if(neurID < START_NEURON_ID){
00609                 qCritical()<<"No neuron selected. You must select a neuron to plot a membrane potential graph.";
00610                 return;
00611         }
00612 
00613         //Do nothing if we are already monitoring this neuron
00614         if(memPotGraphDialogMap.contains(neurID)){
00615                 qDebug()<<"Already monitoring this neuron";
00616                 return;
00617         }
00618 
00619         try{
00620                 //Create raster dialog
00621                 MembranePotentialGraphDialog* memPotDlg = new MembranePotentialGraphDialog(neurID, this);
00622                 memPotDlg->setObjectName(QString::number(neurID));
00623                 connect(memPotDlg, SIGNAL(finished(int)), this, SLOT(deleteMembranePotentialGraphDialog(int)));
00624                 memPotDlg->show();
00625 
00626                 //Store details so that we can update it
00627                 memPotGraphDialogMap[neurID] = memPotDlg;
00628         }
00629         catch(SpikeStreamException& ex){
00630                 qCritical()<<ex.getMessage();
00631         }
00632 }
00633 
00634 
00635 
00637 void NemoWidget::monitorChanged(int state){
00638         try{
00639                 if(state == Qt::Checked){
00640                         nemoWrapper->setMonitor(true);
00641                         if(nemoWrapper->isSimulationLoaded()){
00642                                 timeStepLabel->setText(QString::number(nemoWrapper->getTimeStep()));
00643                         }
00644                         noMonitorNeuronsButton->setEnabled(true);
00645                         monitorFiringNeuronsButton->setEnabled(true);
00646                         monitorMemPotNeuronsButton->setEnabled(true);
00647                         monitorWeightsCheckBox->setEnabled(true);
00648                 }
00649                 else{
00650                         nemoWrapper->setMonitor(false);
00651                         noMonitorNeuronsButton->setEnabled(false);
00652                         monitorFiringNeuronsButton->setEnabled(false);
00653                         monitorMemPotNeuronsButton->setEnabled(false);
00654                         monitorWeightsCheckBox->setEnabled(false);
00655                 }
00656         }
00657         catch(SpikeStreamException& ex){
00658                 qCritical()<<ex.getMessage();
00659         }
00660 }
00661 
00662 
00664 void NemoWidget::monitorNeuronsStateChanged(int monitorType){
00665         try{
00666                 //No monitoring at all
00667                 if(monitorType == MONITOR_NEURONS_OFF){
00668                         nemoWrapper->setMonitorNeurons(false, false);
00669                         rasterButton->setEnabled(false);
00670                         memPotGraphButton->setEnabled(false);
00671                 }
00672                 //Monitoring firing neurons
00673                 else if(monitorType == MONITOR_NEURONS_FIRING){
00674                         nemoWrapper->setMonitorNeurons(true, false);
00675                         rasterButton->setEnabled(true);
00676                         memPotGraphButton->setEnabled(false);
00677                 }
00678                 //Monitoring membrane potential
00679                 else if(monitorType == MONITOR_NEURONS_MEMBRANE){
00680                         nemoWrapper->setMonitorNeurons(false, true);
00681                         rasterButton->setEnabled(false);
00682                         memPotGraphButton->setEnabled(true);
00683                 }
00684                 //Unrecognized value
00685                 else{
00686                         qCritical()<<"Monitor neuron type not recognized: "<<monitorType;
00687                         return;
00688                 }
00689 
00690                 //Clear current highlights
00691                 QHash<unsigned int, RGBColor*>* newHighlightMap = new QHash<unsigned int, RGBColor*>();
00692                 Globals::getNetworkDisplay()->setNeuronColorMap(newHighlightMap);
00693         }
00694         catch(SpikeStreamException& ex){
00695                 qCritical()<<ex.getMessage();
00696         }
00697 }
00698 
00699 
00702 void NemoWidget::nemoWrapperFinished(){
00703         checkForErrors();
00704         unloadSimulation(false);
00705 }
00706 
00707 
00710 void NemoWidget::networkChanged(){
00711         if(nemoWrapper->isSimulationRunning())
00712                 qCritical()<<"Network should not be changed while simulation is running";
00713 
00714         //Unload simulation if it is loaded
00715         unloadSimulation(false);
00716 
00717         //Fix enabled status of toolbar
00718         checkWidgetEnabled();
00719 }
00720 
00721 
00724 void NemoWidget::rasterButtonClicked(){
00725         //Select neuron groups to monitor
00726         NeuronGroupSelectionDialog selectDlg(Globals::getNetwork(), this);
00727         if(selectDlg.exec() == QDialog::Accepted){
00728                 QList<NeuronGroup*> neurGrpList = selectDlg.getNeuronGroups();
00729 
00730                 //Create raster dialog
00731                 SpikeRasterDialog* rasterDlg = new SpikeRasterDialog(neurGrpList, this);
00732                 rasterDlg->setObjectName(QString::number(rasterDialogCtr));
00733                 connect(rasterDlg, SIGNAL(finished(int)), this, SLOT(deleteRasterPlotDialog(int)));
00734                 rasterDlg->show();
00735 
00736                 //Store details so that we can update it
00737                 rasterDialogMap[rasterDialogCtr] = rasterDlg;
00738                 ++rasterDialogCtr;
00739         }
00740 }
00741 
00742 
00745 void NemoWidget::resetWeights(){
00746         //Check user wants to save weights.
00747         int response = QMessageBox::warning(this, "Reset Weights?", "Are you sure that you want to reset the weights.\nThis will overwrite the trained weights and cannot be undone.", QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
00748         if(response != QMessageBox::Ok)
00749                 return;
00750 
00751         try{
00752 
00753                 //Start resetting of weights
00754                 updatingProgress = false;
00755                 taskCancelled = false;
00756                 progressDialog = new QProgressDialog("Resetting weights", "Cancel", 0, 100, this);
00757                 progressDialog->setWindowModality(Qt::WindowModal);
00758                 progressDialog->setMinimumDuration(1000);
00759 
00760                 //Instruct wrapper thread to start saving weights
00761                 nemoWrapper->resetWeights();
00762 
00763                 //Wait for loading to finish and update progress dialog
00764                 heavyTaskTimer  = new QTimer(this);
00765                 connect(heavyTaskTimer, SIGNAL(timeout()), this, SLOT(checkResetWeightsProgress()));
00766                 heavyTaskTimer->start(200);
00767         }
00768         catch(SpikeStreamException& ex){
00769                 qCritical()<<ex.getMessage();
00770         }
00771 }
00772 
00775 void NemoWidget::saveWeights(){
00776         //Check user wants to save weights.
00777         int response = QMessageBox::warning(this, "Save Weights?", "Are you sure that you want to save weights.\nThis will overwrite the current weights in the loaded network.", QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
00778         if(response != QMessageBox::Ok)
00779                 return;
00780 
00781         //Double check that network does not have analyses
00782         if(Globals::getAnalysisDao()->networkHasAnalyses(Globals::getNetwork()->getID())){
00783                 qCritical()<<"Network is linked to analyses - weights cannot be saved until analyses are deleted.";
00784                 return;
00785         }
00786 
00787         try{
00788                 //Start saving of weights
00789                 updatingProgress = false;
00790                 taskCancelled = false;
00791                 progressDialog = new QProgressDialog("Saving weights", "Cancel", 0, 100, this, Qt::CustomizeWindowHint);
00792                 progressDialog->setWindowModality(Qt::WindowModal);
00793                 progressDialog->setMinimumDuration(0);
00794                 progressDialog->setAutoClose(false);
00795                 progressDialog->show();
00796 
00797                 //Instruct wrapper thread to start saving weights
00798                 nemoWrapper->saveWeights();
00799 
00800                 //Wait for loading to finish and update progress dialog
00801                 heavyTaskTimer  = new QTimer(this);
00802                 connect(heavyTaskTimer, SIGNAL(timeout()), this, SLOT(checkSaveWeightsProgress()));
00803                 heavyTaskTimer->start(200);
00804         }
00805         catch(SpikeStreamException& ex){
00806                 qCritical()<<ex.getMessage();
00807         }
00808 }
00809 
00810 
00813 void NemoWidget::setMonitorWeights(bool enable){
00814         nemoWrapper->setMonitorWeights(enable);
00815 }
00816 
00817 
00819 void NemoWidget::setArchiveDescription(){
00820         if(archiveDescriptionEdit->text().isEmpty())
00821                 archiveDescriptionEdit->setText("Undescribed");
00822         if(nemoWrapper->getArchiveID() == 0){
00823                 qCritical()<<"Attempting to set archive description when no archive is in use by NeMo.";
00824                 return;
00825         }
00826         Globals::getArchiveDao()->setArchiveProperties(nemoWrapper->getArchiveID(), archiveDescriptionEdit->text());
00827         Globals::getEventRouter()->archiveListChangedSlot();
00828 }
00829 
00830 
00832 void  NemoWidget::setNeuronParameters(){
00833         NeuronParametersDialog* dialog = new NeuronParametersDialog(this);
00834         dialog->exec();
00835         delete dialog;
00836 }
00837 
00838 
00840 void NemoWidget::setNemoParameters(){
00841         try{
00842                 NemoParametersDialog dialog(nemoWrapper->getNemoConfig(), nemoWrapper->getSTDPFunctionID(), this);
00843                 if(dialog.exec() == QDialog::Accepted){
00844                         nemoWrapper->setNemoConfig(dialog.getNemoConfig());
00845                         nemoWrapper->setSTDPFunctionID(dialog.getSTDPFunctionID());
00846                 }
00847         }
00848         catch(SpikeStreamException& ex){
00849                 qCritical()<<ex.getMessage();
00850         }
00851 }
00852 
00853 
00855 void NemoWidget::setSynapseParameters(){
00856         SynapseParametersDialog* dialog = new SynapseParametersDialog(this);
00857         dialog->exec();
00858         delete dialog;
00859 }
00860 
00861 
00863 void NemoWidget::simulationStopped(){
00864         saveWeightsButton->setEnabled(true);
00865         playAction->setEnabled(true);
00866         stopAction->setEnabled(false);
00867         stepAction->setEnabled(true);
00868         unloadButton->setEnabled(true);
00869         neuronParametersButton->setEnabled(true);
00870 }
00871 
00872 
00875 void NemoWidget::updateTimeStep(unsigned int timeStep){
00876         timeStepLabel->setText(QString::number(timeStep));
00877 
00878         //Allow simulation to proceed on to next step
00879         nemoWrapper->clearWaitForGraphics();
00880 }
00881 
00882 
00885 void NemoWidget::updateTimeStep(unsigned int timeStep, const QList<unsigned>& neuronIDList){
00886         timeStepLabel->setText(QString::number(timeStep));
00887 
00888         //Fill map with neuron ids
00889         QHash<unsigned int, RGBColor*>* newHighlightMap = new QHash<unsigned int, RGBColor*>();
00890         QList<unsigned>::const_iterator endList = neuronIDList.end();
00891         for(QList<unsigned>::const_iterator iter = neuronIDList.begin(); iter != endList; ++iter){
00892                 (*newHighlightMap)[*iter] = neuronColor;
00893         }
00894 
00895         //Set highlight map in network display
00896         Globals::getNetworkDisplay()->setNeuronColorMap(newHighlightMap);
00897 
00898         //Update spike rasters
00899         for(QHash<unsigned, SpikeRasterDialog*>::iterator iter = rasterDialogMap.begin(); iter != rasterDialogMap.end(); ++iter)
00900                 iter.value()->addData(neuronIDList, timeStep);
00901 
00902         //Allow simulation to proceed on to next step
00903         nemoWrapper->clearWaitForGraphics();
00904 }
00905 
00906 
00909 void NemoWidget::updateTimeStep(unsigned int timeStep, const QHash<unsigned, float>& membranePotentialMap){
00910         timeStepLabel->setText(QString::number(timeStep));
00911 
00912         //Fill map with appropriate colours depending on membrane potential.
00913         float tmpMemPot = 0.0f;
00914         QHash<unsigned int, RGBColor*>* newHighlightMap = new QHash<unsigned int, RGBColor*>();
00915         QHash<unsigned, float>::const_iterator endMap = membranePotentialMap.end();
00916         for(QHash<unsigned, float>::const_iterator iter = membranePotentialMap.begin(); iter != endMap; ++iter){
00917                 //Update 3D display
00918                 tmpMemPot = iter.value();
00919                 if(tmpMemPot < -89.0f)
00920                         (*newHighlightMap)[iter.key()] = heatColorMap[-1];
00921                 else if(tmpMemPot < -78.0f)
00922                         (*newHighlightMap)[iter.key()] = heatColorMap[0];
00923                 else if(tmpMemPot < -67.0f)
00924                         (*newHighlightMap)[iter.key()] = heatColorMap[1];
00925                 else if(tmpMemPot < -56.0f)
00926                         (*newHighlightMap)[iter.key()] = heatColorMap[2];
00927                 else if(tmpMemPot < -45.0f)
00928                         (*newHighlightMap)[iter.key()] = heatColorMap[3];
00929                 else if(tmpMemPot < -34.0f)
00930                         (*newHighlightMap)[iter.key()] = heatColorMap[4];
00931                 else if(tmpMemPot < -23.0f)
00932                         (*newHighlightMap)[iter.key()] = heatColorMap[5];
00933                 else if(tmpMemPot < -12.0f)
00934                         (*newHighlightMap)[iter.key()] = heatColorMap[6];
00935                 else if(tmpMemPot < -1.0f)
00936                         (*newHighlightMap)[iter.key()] = heatColorMap[7];
00937                 else if(tmpMemPot < 10.0f)
00938                         (*newHighlightMap)[iter.key()] = heatColorMap[8];
00939                 else if(tmpMemPot < 21.0f)
00940                         (*newHighlightMap)[iter.key()] = heatColorMap[9];
00941                 else
00942                         (*newHighlightMap)[iter.key()] = heatColorMap[10];
00943 
00944                 //Update graphs
00945                 if(memPotGraphDialogMap.contains(iter.key())){
00946                         memPotGraphDialogMap[iter.key()]->addData(iter.value(), timeStep);
00947                 }
00948         }
00949 
00950         //Set network display
00951         Globals::getNetworkDisplay()->setNeuronColorMap(newHighlightMap);
00952 
00953         //Allow simulation to proceed on to next step
00954         nemoWrapper->clearWaitForGraphics();
00955 }
00956 
00957 
00959 void NemoWidget::simulationRateChanged(int){
00960         if(simulationRateCombo->currentText() == "Max")
00961                 nemoWrapper->setFrameRate(0);
00962         else{
00963                 unsigned int frameRate = Util::getUInt(simulationRateCombo->currentText());
00964                 nemoWrapper->setFrameRate(frameRate);
00965         }
00966 }
00967 
00968 
00970 void NemoWidget::startSimulation(){
00971         //Do nothing if there is no simulation loaded or if wrapper is busy
00972         if(!nemoWrapper->isSimulationLoaded()){
00973                 return;
00974         }
00975         try{
00976                 nemoWrapper->playSimulation();
00977                 playAction->setEnabled(false);
00978                 stopAction->setEnabled(true);
00979                 stepAction->setEnabled(false);
00980                 unloadButton->setEnabled(false);
00981                 neuronParametersButton->setEnabled(false);
00982                 saveWeightsButton->setEnabled(false);
00983         }
00984         catch(SpikeStreamException& ex){
00985                 qCritical()<<ex.getMessage();
00986         }
00987 }
00988 
00989 
00991 void NemoWidget::startStopSimulation(){
00992         //Do nothing if there is no simulation loaded or if wrapper is busy
00993         if(!nemoWrapper->isSimulationLoaded()){
00994                 return;
00995         }
00996         if(nemoWrapper->getCurrentTask() == NemoWrapper::NO_TASK_DEFINED)
00997                 startSimulation();
00998         else if(nemoWrapper->getCurrentTask() == NemoWrapper::RUN_SIMULATION_TASK)
00999                 stopSimulation();
01000 }
01001 
01002 
01004 void NemoWidget::stepSimulation(){
01005         //Do nothing if there is no simulation loaded or if wrapper is busy
01006         if(!nemoWrapper->isSimulationLoaded() || nemoWrapper->getCurrentTask() != NemoWrapper::NO_TASK_DEFINED){
01007                 return;
01008         }
01009 
01010         //Step simulation
01011         try{
01012                 nemoWrapper->stepSimulation();
01013         }
01014         catch(SpikeStreamException& ex){
01015                 qCritical()<<ex.getMessage();
01016         }
01017 }
01018 
01019 
01021 void NemoWidget::stopSimulation(){
01022         //Do nothing if there is no simulation loaded
01023         if(!nemoWrapper->isSimulationLoaded()){
01024                 return;
01025         }
01026 
01027         nemoWrapper->stopSimulation();
01028 }
01029 
01030 
01033 void NemoWidget::sustainNoiseChanged(bool enabled){
01034         if(enabled){
01035                 injectNoiseButton->setEnabled(false);
01036                 injectNoisePercentCombo->setEnabled(false);
01037                 injectNoiseCurrentCombo->setEnabled(false);
01038                 injectNoiseNeuronGroupCombo->setEnabled(false);
01039                 setInjectNoise(true);
01040         }
01041         else{
01042                 injectNoiseButton->setEnabled(true);
01043                 injectNoisePercentCombo->setEnabled(true);
01044                 injectNoiseCurrentCombo->setEnabled(true);
01045                 injectNoiseNeuronGroupCombo->setEnabled(true);
01046 
01047                 //Switch off sustain noise - it will be automatically deleted on next step.
01048                 nemoWrapper->setSustainNoise(false);
01049         }
01050 }
01051 
01054 void NemoWidget::sustainPatternChanged(bool enabled){
01055         if(enabled){
01056                 injectPatternButton->setEnabled(false);
01057                 injectPatternNeurGrpCombo->setEnabled(false);
01058                 patternCombo->setEnabled(false);
01059                 patternCurrentCombo->setEnabled(false);
01060                 setInjectionPattern(true);
01061         }
01062         else{
01063                 injectPatternButton->setEnabled(true);
01064                 injectPatternNeurGrpCombo->setEnabled(true);
01065                 patternCombo->setEnabled(true);
01066                 patternCurrentCombo->setEnabled(true);
01067 
01068                 //Switch off sustain pattern - the pattern will be automatically deleted on next step.
01069                 nemoWrapper->setSustainPattern(false);
01070         }
01071 }
01072 
01073 
01075 void NemoWidget::unloadSimulation(bool confirmWithUser){
01076         //Double check that user wants to unload simulation
01077         if(confirmWithUser){
01078                 int response = QMessageBox::warning(this, "Unload?", "Are you sure that you want to unload the simulation?\nAny unsaved weight changes will be lost.", QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
01079                 if(response != QMessageBox::Ok)
01080                         return;
01081         }
01082 
01083         //Unload the simulation
01084         nemoWrapper->unloadSimulation();
01085         Globals::setSimulation(NULL);
01086 
01087         //Clear network display
01088         Globals::getNetworkDisplay()->setNeuronColorMap(new QHash<unsigned int, RGBColor*>());
01089 
01090         //Set buttons appropriately
01091         loadButton->setEnabled(true);
01092         unloadButton->setEnabled(false);
01093         synapseParametersButton->setEnabled(true);
01094         nemoParametersButton->setEnabled(true);
01095         controlsWidget->setEnabled(false);
01096         archiveDescriptionEdit->setText("Undescribed");
01097         archiveCheckBox->setChecked(false);//Single archive associated with each simulation run
01098         timeStepLabel->setText("0");
01099 
01100         //Inject patterns, current etc.
01101         sustainPatternChkBox->setChecked(false);
01102         injectPatternButton->setEnabled(true);
01103         injectPatternNeurGrpCombo->setEnabled(true);
01104         patternCombo->setEnabled(true);
01105         patternCurrentCombo->setEnabled(true);
01106 
01107         sustainNoiseChkBox->setChecked(false);
01108         injectNoiseButton->setEnabled(true);
01109         injectNoisePercentCombo->setEnabled(true);
01110         injectNoiseCurrentCombo->setEnabled(true);
01111         injectNoiseNeuronGroupCombo->setEnabled(true);
01112 
01113         //Clean up any raster plots
01114         for(QHash<unsigned, SpikeRasterDialog*>::iterator iter = rasterDialogMap.begin(); iter != rasterDialogMap.end(); ++iter){
01115                 delete iter.value();
01116         }
01117         rasterDialogMap.clear();
01118 
01119         //Clean up any membrane potential plots
01120         for(QHash<unsigned, MembranePotentialGraphDialog*>::iterator iter = memPotGraphDialogMap.begin(); iter != memPotGraphDialogMap.end(); ++iter){
01121                 delete iter.value();
01122         }
01123         memPotGraphDialogMap.clear();
01124 }
01125 
01126 
01128 void NemoWidget::updateProgress(int stepsCompleted, int totalSteps){
01129         //Set flag to avoid multiple calls to progress dialog while it is redrawing
01130         if(updatingProgress)
01131                 return;
01132         updatingProgress = true;
01133 
01134         if(progressDialog == NULL)
01135                 return;
01136 
01137         //Check numbers are sensible
01138         if(stepsCompleted > totalSteps){
01139                 qCritical()<<"Progress update error: Number of steps completed is greater than the number of possible steps.";
01140                 return;
01141         }
01142 
01143         //Update progress
01144         if(stepsCompleted < totalSteps){
01145                 progressDialog->setValue(stepsCompleted);
01146                 progressDialog->setMaximum(totalSteps);
01147         }
01148 
01149         //Clear updating progress flag
01150         updatingProgress = false;
01151 }
01152 
01153 
01154 /*----------------------------------------------------------*/
01155 /*------               PRIVATE METHODS                ------*/
01156 /*----------------------------------------------------------*/
01157 
01159 bool NemoWidget::checkForErrors(){
01160         if(nemoWrapper->isError()){
01161                 qCritical()<<"NemoWrapper error: '"<<nemoWrapper->getErrorMessage()<<"'.";
01162                 return true;
01163         }
01164         return false;
01165 }
01166 
01167 
01169 void NemoWidget::checkWidgetEnabled(){
01170         if(Globals::networkLoaded())
01171                 mainGroupBox->setEnabled(true);
01172         else
01173                 mainGroupBox->setEnabled(false);
01174 }
01175 
01176 
01178 void NemoWidget::createMembranePotentialColors(){
01179                 heatColorMap[-1] = new RGBColor(0.0f, 0.0f, 0.0f);
01180                 Globals::getNetworkDisplay()->addDefaultColor(heatColorMap[-1]);
01181                 heatColorMap[0] = new RGBColor(HEAT_COLOR_0);
01182                 Globals::getNetworkDisplay()->addDefaultColor(heatColorMap[0]);
01183                 heatColorMap[1] = new RGBColor(HEAT_COLOR_1);
01184                 Globals::getNetworkDisplay()->addDefaultColor(heatColorMap[1]);
01185                 heatColorMap[2] = new RGBColor(HEAT_COLOR_2);
01186                 Globals::getNetworkDisplay()->addDefaultColor(heatColorMap[2]);
01187                 heatColorMap[3] = new RGBColor(HEAT_COLOR_3);
01188                 Globals::getNetworkDisplay()->addDefaultColor(heatColorMap[3]);
01189                 heatColorMap[4] = new RGBColor(HEAT_COLOR_4);
01190                 Globals::getNetworkDisplay()->addDefaultColor(heatColorMap[4]);
01191                 heatColorMap[5] = new RGBColor(HEAT_COLOR_5);
01192                 Globals::getNetworkDisplay()->addDefaultColor(heatColorMap[5]);
01193                 heatColorMap[6] = new RGBColor(HEAT_COLOR_6);
01194                 Globals::getNetworkDisplay()->addDefaultColor(heatColorMap[6]);
01195                 heatColorMap[7] = new RGBColor(HEAT_COLOR_7);
01196                 Globals::getNetworkDisplay()->addDefaultColor(heatColorMap[7]);
01197                 heatColorMap[8] = new RGBColor(HEAT_COLOR_8);
01198                 Globals::getNetworkDisplay()->addDefaultColor(heatColorMap[8]);
01199                 heatColorMap[9] = new RGBColor(HEAT_COLOR_9);
01200                 Globals::getNetworkDisplay()->addDefaultColor(heatColorMap[9]);
01201                 heatColorMap[10] = new RGBColor(HEAT_COLOR_10);
01202                 Globals::getNetworkDisplay()->addDefaultColor(heatColorMap[10]);
01203 }
01204 
01205 
01207 void NemoWidget::fillPatternCurrentCombo(){
01208         patternCurrentCombo->addItem("Fire");
01209         for(int i=0; i<=100; i+=10)
01210                 patternCurrentCombo->addItem(QString::number(i));
01211 }
01212 
01214 QString NemoWidget::getFilePath(QString fileFilter){
01215         QFileDialog dialog(this);
01216         dialog.setDirectory(Globals::getWorkingDirectory());
01217         dialog.setFileMode(QFileDialog::ExistingFile);
01218         dialog.setNameFilter( QString("Configuration files (" + fileFilter + ")") );
01219         dialog.setViewMode(QFileDialog::Detail);
01220         QStringList fileNames;
01221         if (dialog.exec())
01222                 fileNames = dialog.selectedFiles();
01223         if(fileNames.size() > 0)
01224                 return fileNames[0];
01225         else
01226                 return QString("");
01227 }
01228 
01229 
01231 unsigned NemoWidget::getNeuronGroupID(QString neurGrpStr){
01232         QRegExp regExp("[()]");
01233         return Util::getUInt(neurGrpStr.section(regExp, 1, 1));
01234 }
01235 
01236 
01241 QString NemoWidget::getPatternKey(const QString& patternComboText){
01242         if(patternComboText == LOAD_PATTERN_STRING){
01243                 throw SpikeStreamException("Cannot inject pattern: no patterns added.");
01244         }
01245 
01246         //Find the key to the pattern in the pattern map
01247         QString patternKey = "";
01248         for(QHash<QString, Pattern>::iterator iter = patternMap.begin(); iter != patternMap.end(); ++iter){
01249                 if(iter.value().getName() == patternComboText){
01250                         patternKey = iter.key();
01251                         break;
01252                 }
01253         }
01254 
01255         //Check that key has been found
01256         if(patternKey.isEmpty()){
01257                 throw SpikeStreamException("Pattern not found: " + patternComboText);
01258         }
01259 
01260         return patternKey;
01261 }
01262 
01263 
01265 QToolBar* NemoWidget::getToolBar(){
01266         QToolBar* tmpToolBar = new QToolBar(this);
01267 
01268         playAction = new QAction(QIcon(Globals::getSpikeStreamRoot() + "/images/play.png"), "Start simulation", this);
01269         connect(playAction, SIGNAL(triggered()), this, SLOT(startSimulation()));
01270         tmpToolBar->addAction (playAction);
01271 
01272         stopAction = new QAction(QIcon(Globals::getSpikeStreamRoot() + "/images/stop.png"), "Stop simulation", this);
01273         connect(stopAction, SIGNAL(triggered()), this, SLOT(stopSimulation()));
01274         stopAction->setEnabled(false);
01275         tmpToolBar->addAction (stopAction);
01276 
01277         stepAction = new QAction(QIcon(Globals::getSpikeStreamRoot() + "/images/step.png"), "Step simulation", this);
01278         connect(stepAction, SIGNAL(triggered()), this, SLOT(stepSimulation()));
01279         tmpToolBar->addAction (stepAction);
01280 
01281         simulationRateCombo = new QComboBox();
01282         simulationRateCombo->addItem("1");
01283         simulationRateCombo->addItem("5");
01284         simulationRateCombo->addItem("10");
01285         simulationRateCombo->addItem("15");
01286         simulationRateCombo->addItem("20");
01287         simulationRateCombo->addItem("25");
01288         simulationRateCombo->addItem("Max");
01289         connect(simulationRateCombo, SIGNAL(activated(int)), this, SLOT(simulationRateChanged(int)));
01290         tmpToolBar->addWidget(simulationRateCombo);
01291 
01292         timeStepLabel = new QLabel ("0");
01293         timeStepLabel->setStyleSheet( "QLabel { margin-left: 5px; background-color: #ffffff; border-color: #555555; border-width: 2px; border-style: outset; font-weight: bold;}");
01294         timeStepLabel->setMinimumSize(200, 20);
01295         timeStepLabel->setMaximumSize(200, 20);
01296         timeStepLabel->setAlignment(Qt::AlignCenter);
01297         tmpToolBar->addWidget(timeStepLabel);
01298 
01299         QCheckBox* monitorChkBox = new QCheckBox("Monitor");
01300         monitorChkBox->setChecked(true);
01301         connect(monitorChkBox, SIGNAL(stateChanged(int)), this, SLOT(monitorChanged(int)));
01302         tmpToolBar->addSeparator();
01303         tmpToolBar->addWidget(monitorChkBox);
01304 
01305         return tmpToolBar;
01306 }
01307 
01309 void NemoWidget::loadNeuronGroups(){
01310         injectNoiseNeuronGroupCombo->clear();
01311         injectPatternNeurGrpCombo->clear();
01312 
01313         QList<NeuronGroupInfo> neurGrpInfoList = Globals::getNetwork()->getNeuronGroupsInfo();
01314         foreach(NeuronGroupInfo info, neurGrpInfoList){
01315                 injectNoiseNeuronGroupCombo->addItem(info.getName() + "(" + QString::number(info.getID()) + ")");
01316                 injectPatternNeurGrpCombo->addItem(info.getName() + "(" + QString::number(info.getID()) + ")");
01317         }
01318 }
01319 
01320 
01322 void NemoWidget::setInjectNoise(bool sustain){
01323         double percentage = Util::getDouble(injectNoisePercentCombo->currentText().section(" ", 0, 0));
01324         unsigned neurGrpID = getNeuronGroupID(injectNoiseNeuronGroupCombo->currentText());
01325         try{
01326                 if(injectNoiseCurrentCombo->currentText() == "Fire"){
01327                         nemoWrapper->setInjectNoise(neurGrpID, percentage, sustain);
01328                 }
01329                 else{
01330                         nemoWrapper->setInjectCurrent(neurGrpID, percentage, Util::getDouble(injectNoiseCurrentCombo->currentText()), sustain);
01331                 }
01332         }
01333         catch(SpikeStreamException& ex){
01334                 qCritical()<<ex.getMessage();
01335         }
01336 }
01337 
01338 
01340 void NemoWidget::setInjectionPattern(bool sustain){
01341         //Set pattern in the nemo wrapper
01342         try{
01343                 if(patternCurrentCombo->currentIndex() == 0)//Fire neurons
01344                         nemoWrapper->setFiringInjectionPattern(
01345                                         patternMap[getPatternKey(patternCombo->currentText())],
01346                                         getNeuronGroupID(injectPatternNeurGrpCombo->currentText()),
01347                                         sustain
01348                         );
01349                 else{
01350                         float injectionCurrent = Util::getFloat(patternCurrentCombo->currentText());
01351                         nemoWrapper->setCurrentInjectionPattern(
01352                                         patternMap[getPatternKey(patternCombo->currentText())],
01353                                         injectionCurrent,
01354                                         getNeuronGroupID(injectPatternNeurGrpCombo->currentText()),
01355                                         sustain
01356                         );
01357                 }
01358         }
01359         catch(SpikeStreamException& ex){
01360                 qCritical()<<ex.getMessage();
01361         }
01362 }
01363 
 All Classes Files Functions Variables Typedefs Defines