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

LayerPropertiesDialog.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 "LayerPropertiesDialog.h"
00025 #include "LayerManager.h"
00026 #include "Debug.h"
00027 #include "Utilities.h"
00028 #include "NeuronGroup.h"
00029 #include "NeuronGroupType.h"
00030 
00031 //Qt includes
00032 #include <qlayout.h>
00033 #include <qlabel.h>
00034 #include <qaccel.h>
00035 #include <qpushbutton.h>
00036 #include <qvalidator.h>
00037 #include <qmessagebox.h>
00038 #include <qstring.h>
00039 #include <qregexp.h>
00040 
00041 //Other includes
00042 #include <string>
00043 #include <sstream>
00044 #include <iostream>
00045 #include "mysql++.h"
00046 using namespace std;
00047 using namespace mysqlpp;
00048 
00049 
00050 /*! Constructor. */
00051 LayerPropertiesDialog::LayerPropertiesDialog(QWidget *parent, const char *name, bool edMode, NeuronGroup &neuronGrp, DBInterface* netDBInter, DBInterface* devDBInter) : QDialog(parent, name){
00052         //Store references to databases
00053         networkDBInterface = netDBInter;
00054         deviceDBInterface = devDBInter;
00055 
00056         /* In editMode, the dialog displays information about an existing layer for editing
00057                 Otherwise an entirely new layer is created.     */
00058         editMode = edMode;
00059 
00060         //Initialise unrecognized neuron type index
00061         unknownNeuronTypeIndex = -1;
00062 
00063         //Create box to organise vertical layout of dialog
00064         QVBoxLayout *vBox = new QVBoxLayout(this, 5, 5, "Main vertical Box");
00065         
00066         //Validators used to check for the correct input
00067         QValidator* coordinateIntValidator = new QIntValidator(-10000, 10000, this);
00068         QValidator * dimensionsValidator = new QIntValidator(2, 500, this);
00069         QValidator * neuronSpacingValidator = new QIntValidator(1, 1000, this);
00070         QRegExp regExp( "([0-9]|[A-Z]|[a-z]|_|\\s){1,50}" );
00071     QValidator* nameValidator = new QRegExpValidator(regExp, this);
00072 
00073         //Set up name field
00074         QHBoxLayout *nameBox = new QHBoxLayout();
00075         nameBox->addWidget(new QLabel("Name", this));
00076         if(editMode)
00077                 nameText = new QLineEdit(neuronGrp.name, this);
00078         else
00079                 nameText = new QLineEdit("Untitled", this);
00080         nameText->setValidator(nameValidator);
00081         nameBox->addWidget(nameText);
00082         vBox->addLayout(nameBox);
00083 
00084         //Set up combo to select the type of layer
00085         if(!editMode){//Can't change the type so not much point in displaying it in edit mode
00086                 QHBoxLayout *neurGrpTypeBox = new QHBoxLayout();
00087                 neurGrpTypeCombo = new QComboBox(this, "Neuron Group Type");
00088                 neurGrpTypeCombo->setMinimumSize(250,30);
00089                 fillNeurGrpTypeCombo();
00090 
00091                 /* Connect combo up with slot so that changes in the selection
00092                         alter the available widgets. */
00093                 connect (neurGrpTypeCombo, SIGNAL(activated(int)), this, SLOT(neuronGrpTypeChanged(int)));
00094         
00095                 //Add the neuron group type combo
00096                 neurGrpTypeBox->addWidget(new QLabel("Neuron Group Type", this, "Neuron group type"));
00097                 neurGrpTypeBox->addWidget(neurGrpTypeCombo);
00098                 neurGrpTypeBox->addStretch(3);
00099                 vBox->addLayout(neurGrpTypeBox);
00100         
00101                 //Add the combo to select the input layer
00102                 QHBoxLayout* inputLayerBox = new QHBoxLayout();
00103                 inputLayerLabel = new QLabel("Device input/output layer", this);
00104                 inputLayerLabel->hide();
00105                 inputLayerBox->addWidget(inputLayerLabel);
00106                 inputLayerCombo = new QComboBox(this);
00107                 inputLayerCombo->hide();
00108                 inputLayerCombo->setMinimumSize(250,30);
00109         
00110                 /* Connect the input layer combo up with a slot so that for each
00111                         input layer, the available components are displayed */
00112                 connect (inputLayerCombo, SIGNAL(activated(int)), this, SLOT(inputLayerComboChanged(int)));
00113         
00114                 //Add the input layer combo
00115                 inputLayerBox->addWidget(inputLayerCombo);
00116                 inputLayerBox->addStretch(5);
00117                 vBox->addLayout(inputLayerBox);
00118         
00119                 //Add the combo to select the component
00120                 QHBoxLayout* componentBox = new QHBoxLayout();
00121                 componentLabel = new QLabel("SIMNOS component", this);
00122                 componentLabel->hide();
00123                 componentBox->addWidget(componentLabel);
00124                 componentCombo = new QComboBox(this);
00125                 componentCombo->hide();
00126                 componentCombo->setMinimumSize(250,30);
00127                 componentBox->addWidget(componentCombo);
00128                 componentBox->addStretch(5);
00129                 vBox->addLayout(componentBox);
00130         }
00131 
00132         //Set up neuron type field
00133         QHBoxLayout *neuronTypeBox = new QHBoxLayout();
00134         neuronTypeCombo = new QComboBox(this, "Neuron Types");
00135 
00136         //Load up the neuron types from the database
00137         bool neuronTypeFound = false;
00138         int counter = 0, neuronTypeComboIndex = 0;
00139         try{
00140                 Query query = networkDBInterface->getQuery();
00141                 query.reset();
00142                 query<<"SELECT TypeID, Description FROM NeuronTypes";
00143                 Result typeResult = query.store();
00144                 for(Result::iterator iter = typeResult.begin(); iter != typeResult.end(); ++iter){
00145                         Row neurTypeRow(*iter);
00146                         unsigned short neuronTypeID = Utilities::getUShort((std::string) neurTypeRow["TypeID"]);
00147         
00148                         //Store link between neuron type and combo index
00149                         neuronTypePositionMap[counter] = neuronTypeID;
00150                         QString typeDescription = (std::string) neurTypeRow["Description"];
00151                         typeDescription += " [" + (std::string) neurTypeRow["TypeID"] + "]";
00152                         neuronTypeCombo->insertItem(typeDescription);
00153                         if(editMode){
00154                                 if(neuronTypeID == neuronGrp.neuronType){
00155                                         neuronTypeComboIndex = counter;
00156                                         neuronTypeFound = true;
00157                                 }
00158                         }
00159                         counter++;
00160                 }
00161         }
00162     catch (const BadQuery& er) {// Handle any query errors
00163                 cerr<<"LayerPropertiesDialog: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00164                 QString errorString = "Bad query loading neuron types: \"";
00165                 errorString += er.what();
00166                 errorString += "\"";
00167                 QMessageBox::critical( 0, "Neuron Types Error", errorString);
00168     }
00169     catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00170         cerr<<"LayerPropertiesDialog: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00171                 QString errorString = "Exception thrown loading neuron types: \"";
00172                 errorString += er.what();
00173                 errorString += "\"";
00174                 QMessageBox::critical( 0, "Neuron Types Error", errorString);
00175         }
00176         catch(std::exception& er){// Catch-all for std exceptions
00177                 cerr<<"LayerPropertiesDialog: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00178                 QString errorString = "Exception thrown loading neuron types: \"";
00179                 errorString += er.what();
00180                 errorString += "\"";
00181                 QMessageBox::critical( 0, "Neuron Types Error", errorString);
00182         }
00183 
00184         if(editMode && !neuronTypeFound){
00185                 neuronTypeCombo->insertItem("Unknown");
00186                 neuronTypeCombo->setCurrentItem(counter);
00187                 unknownNeuronTypeIndex = counter;
00188         }
00189         else{
00190                 neuronTypeCombo->setCurrentItem(neuronTypeComboIndex);
00191         }
00192         neuronTypeBox->addWidget(new QLabel("Neuron Type", this, "Neuron type"));
00193         neuronTypeBox->addWidget(neuronTypeCombo);
00194         vBox->addLayout(neuronTypeBox);
00195 
00196         //Set up width in neurons field
00197         //This cannot be changed in editMode since the connections will be affected
00198         QHBoxLayout *widthBox = new QHBoxLayout();
00199         widthBox->addWidget(new QLabel("Width (neurons)", this, "Width neurons"));
00200         widthText = new QLineEdit(this);
00201         widthText->setMaximumSize(50,20);
00202         widthText->setValidator( dimensionsValidator );
00203         widthBox->addWidget(widthText);
00204         if(editMode){
00205                 widthText->setText(QString::number(neuronGrp.width));
00206                 widthText->setReadOnly(true);
00207         }
00208         widthBox->addStretch(5);
00209         vBox->addLayout(widthBox);
00210         
00211         //Set up length in neurons field
00212         QHBoxLayout *lengthBox = new QHBoxLayout();
00213         lengthBox->addWidget(new QLabel("Length (neurons)", this, "Length neurons"));
00214         lengthText = new QLineEdit(this);
00215         lengthText->setMaximumSize(50,20);
00216         lengthText->setValidator( dimensionsValidator );
00217         lengthBox->addWidget(lengthText);
00218         if(editMode){
00219                 lengthText->setText(QString::number(neuronGrp.length));
00220                 lengthText->setReadOnly(true);
00221         }
00222         lengthBox->addStretch(5);
00223         vBox->addLayout(lengthBox);
00224         
00225         //Set up neuron spacing field
00226         QHBoxLayout *neuronSpacingBox = new QHBoxLayout();
00227         neuronSpacingLabel = new QLabel("Neuron Spacing", this, "Neuron Spacing label");
00228         neuronSpacingBox->addWidget(neuronSpacingLabel);
00229         if(editMode)
00230                 neuronSpacingText = new QLineEdit(QString::number(neuronGrp.spacing), this);
00231         else
00232                 neuronSpacingText = new QLineEdit(DEFAULT_NEURON_SPACING, this, "Neuron spacing" );
00233         neuronSpacingText->setValidator( neuronSpacingValidator );
00234         neuronSpacingBox->addWidget(neuronSpacingText);
00235         vBox->addLayout(neuronSpacingBox);
00236         
00237         //Set up layer center position
00238         QHBoxLayout *layerPositionBox = new QHBoxLayout();
00239         layerPositionBox->addWidget(new QLabel("Location", this, "Layer centre"));
00240         layerPositionBox->addSpacing(5);
00241         layerPositionBox->addWidget(new QLabel("X:", this, "xpos"));
00242         if(editMode)
00243                 xPosText = new QLineEdit(QString::number(neuronGrp.xPos), this);
00244         else
00245                 xPosText = new QLineEdit(this);
00246         xPosText->setValidator( coordinateIntValidator );
00247         xPosText->setMaximumSize(50,20);
00248         layerPositionBox->addWidget(xPosText);
00249         layerPositionBox->addSpacing(5);
00250         layerPositionBox->addWidget(new QLabel("Y:", this, "ypos"));
00251         if(editMode)
00252                 yPosText = new QLineEdit(QString::number(neuronGrp.yPos),this);
00253         else
00254                 yPosText = new QLineEdit(this);
00255         yPosText->setValidator( coordinateIntValidator );
00256         yPosText->setMaximumSize(50,20);
00257         layerPositionBox->addWidget(yPosText);
00258         layerPositionBox->addSpacing(5);
00259         layerPositionBox->addWidget(new QLabel("Z:", this, "zpos"));
00260         if(editMode)
00261                 zPosText = new QLineEdit(QString::number(neuronGrp.zPos), this);
00262         else
00263                 zPosText = new QLineEdit(this);
00264         zPosText->setValidator( coordinateIntValidator );
00265         zPosText->setMaximumSize(50,20);
00266         layerPositionBox->addWidget(zPosText);
00267         layerPositionBox->addStretch(5);
00268         vBox->addLayout(layerPositionBox);
00269 
00270         //Set up ok and cancel buttons
00271         QHBoxLayout *buttonBox = new QHBoxLayout();
00272         QPushButton *okPushButton = new QPushButton("Ok", this, "okButton");
00273         QPushButton *cancelPushButton = new QPushButton("Cancel", this, "cancelButton");        
00274         buttonBox->addWidget(okPushButton);
00275         buttonBox->addWidget(cancelPushButton);
00276         vBox->addLayout(buttonBox);
00277         
00278         connect (okPushButton, SIGNAL(clicked()), this, SLOT(okButtonPressed()));
00279         connect (cancelPushButton, SIGNAL(clicked()), this, SLOT(reject()));
00280         
00281         //Set up accelerator for return button
00282         QAccel *returnAccel = new QAccel( this );
00283     returnAccel->connectItem( returnAccel->insertItem( Key_Enter ), this, SLOT(okButtonPressed()));
00284 
00285         /* Load up the combos - do this last because they depend on other 
00286                 components, which need to be initialised. */
00287         if(!editMode)
00288                 loadInputLayers();
00289 }
00290 
00291 
00292 /*! Destructor. Qt widgets should be deleted automatically since
00293         they are all created with a reference to this. */
00294 LayerPropertiesDialog::~LayerPropertiesDialog(){
00295         #ifdef MEMORY_DEBUG
00296                 cout<<"DELETING LAYER PROPERTIES DIALOG"<<endl;
00297         #endif//MEMORY_DEBUG
00298 }
00299 
00300 
00301 //---------------------------------------------------------------------
00302 //------------------------ PUBLIC METHODS -----------------------------
00303 //---------------------------------------------------------------------
00304 
00305 /*! Returns the structure NeuronGrpHolder containing all the information about the layer. */
00306 NeuronGroup LayerPropertiesDialog::getNeuronGroup(){
00307         //Create the neuron group holder
00308         NeuronGroup neuronGrp;
00309 
00310         //Add connection type to neuron group holder
00311         try{
00312                 if(!editMode){
00313                         string connectionText = neurGrpTypeCombo->currentText().ascii();
00314                         neuronGrp.neuronGrpType = NeuronGroupType::getType(connectionText);
00315                 
00316                         //Add component id and deviceNeuronGrpID if applicable
00317                         if(NeuronGroupType::getType(neurGrpTypeCombo->currentText()) == NeuronGroupType::SIMNOSComponentLayer){
00318                                 neuronGrp.componentID = Utilities::getNeuronGrpID(componentCombo->currentText());//Not a neuron group id, but extraction method is the same
00319                                 neuronGrp.deviceNeuronGrpID = Utilities::getNeuronGrpID(inputLayerCombo->currentText());
00320                         }
00321                 }
00322         
00323                 //Need to convert from combo box selection to the unsigned short representing the neuron type
00324                 int comboIndex = neuronTypeCombo->currentItem();
00325                 neuronGrp.neuronType =  neuronTypePositionMap[comboIndex];
00326                 
00327                 //Extract the rest of the information
00328                 neuronGrp.name = nameText->text();
00329                 neuronGrp.width = Utilities::getUInt(widthText->text().ascii());
00330                 neuronGrp.length = Utilities::getUInt(lengthText->text().ascii());
00331                 neuronGrp.spacing = Utilities::getUInt(neuronSpacingText->text().ascii());
00332                 neuronGrp.xPos = Utilities::getInt(xPosText->text().ascii());
00333                 neuronGrp.yPos = Utilities::getInt(yPosText->text().ascii());
00334                 neuronGrp.zPos = Utilities::getInt(zPosText->text().ascii());
00335         }
00336     catch (const std::exception& er) {// Catch-all for any other MySQL++ exceptions
00337         cerr<<"LayerPropertiesDialog: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00338                 QString errorString = "Exception thrown getting neuron group: \"";
00339                 errorString += er.what();
00340                 errorString += "\"";
00341                 QMessageBox::critical( 0, "Neuron Group Error", errorString);
00342     }
00343         return neuronGrp;
00344 }
00345 
00346 
00347 //-----------------------------------------------------------------------------------
00348 //-------------------------------------- SLOTS --------------------------------------
00349 //-----------------------------------------------------------------------------------
00350 
00351 /*! Called when the component combo selection is changed. */
00352 void LayerPropertiesDialog::componentComboChanged(int comboIndex){
00353         if(noComponents || NeuronGroupType::getType(neurGrpTypeCombo->currentText()) != NeuronGroupType::SIMNOSComponentLayer){
00354                 widthText->clear();
00355                 lengthText->clear();
00356         }
00357         else{
00358                 widthText->setText(QString::number(componentWidthMap[comboIndex]));
00359                 lengthText->setText(QString::number(componentLengthMap[comboIndex]));
00360         }
00361 }
00362 
00363 
00364 /*! Called when the input layer combo is changed. 
00365         This method sets the available SIMNOS components. */
00366 void LayerPropertiesDialog::inputLayerComboChanged(int){
00367         //Clear component combo and associated maps
00368         componentCombo->clear();
00369         componentWidthMap.clear();
00370         componentLengthMap.clear();
00371         noComponents = true;
00372 
00373         //If there are no viable input layers, reset combo and return
00374         if(noInputLayers){
00375                 componentCombo->insertItem("No matching components", -1);
00376                 widthText->clear();
00377                 lengthText->clear();
00378                 return;
00379         }
00380         
00381         try{
00382                 //Get current neuron group id
00383                 unsigned int inputNeurGrpID = Utilities::getNeuronGrpID(inputLayerCombo->currentText());
00384 
00385                 //Find the width and length of this neuron group
00386                 Query networkQuery = networkDBInterface->getQuery();
00387                 networkQuery.reset();
00388                 networkQuery<<"SELECT Width, Length FROM NeuronGroups WHERE NeuronGrpID = "<<inputNeurGrpID;
00389                 Result neurGrpResult= networkQuery.store();
00390                 Row neurGrpRow (*neurGrpResult.begin());//NeuronGrpID should be unique
00391                 unsigned int neurGrpWidth = Utilities::getUInt((std::string)neurGrpRow["Width"]);
00392                 unsigned int neurGrpLength = Utilities::getUInt((std::string)neurGrpRow["Length"]);
00393         
00394                 //Need all the devices that match this width and length
00395                 QStringList deviceDescriptionList;
00396                 Query deviceQuery = deviceDBInterface->getQuery();
00397                 deviceQuery.reset();
00398                 deviceQuery<<"SELECT Description FROM Devices WHERE TotalNumColumns = "<<neurGrpWidth<<" AND TotalNumRows = "<<neurGrpLength;
00399                 Result deviceDescRes = deviceQuery.store();
00400                 for(Result::iterator devDescIter = deviceDescRes.begin(); devDescIter != deviceDescRes.end(); ++devDescIter){
00401                         Row deviceDescRow(*devDescIter);
00402                         QString deviceDescriptionString((std::string)deviceDescRow["Description"]);
00403                         deviceDescriptionList += deviceDescriptionString;
00404                 }
00405         
00406                 /* Work through the SIMNOS components. */
00407                 deviceQuery.reset();
00408                 deviceQuery<<"SELECT Name, ComponentID, ReceptorIDs, Width, Length FROM SIMNOSComponents";
00409                 Result simnosRes = deviceQuery.store();
00410                 for(Result::iterator simnosIter = simnosRes.begin(); simnosIter != simnosRes.end(); ++simnosIter){
00411                         Row simnosRow(*simnosIter);
00412                         
00413                         //Extract the first receptor id in the list
00414                         //NOTE THIS ASSUMES THAT ALL OF THE RECEPTORS ARE FROM THE SAME DEVICE
00415                         QString receptorIDString = (std::string)simnosRow["ReceptorIDs"];
00416                         if(receptorIDString.isEmpty()){
00417                                 cerr<<"LayerPropertiesDialog: NO RECEPTOR IDS FOR THIS COMPONENT"<<endl;
00418                                 QMessageBox::critical (this, "SIMNOS Component Error", "No receptor list for this component");
00419                                 return;
00420                         }
00421         
00422                         //Get the receptor ID - converting to int is a good check
00423                         unsigned int firstReceptorID = Utilities::getUInt(receptorIDString.section(',', 0, 0).ascii());
00424                         
00425                         deviceQuery.reset();
00426                         deviceQuery<<"SELECT DeviceDescription FROM SIMNOSSpikeReceptors WHERE ReceptorID = "<<firstReceptorID;
00427                         Result receptorDevDesRes = deviceQuery.store();
00428                         Row receptorDevDesRow(*receptorDevDesRes.begin());//ReceptorID should be unique
00429                         QString receptorDeviceDesc ((std::string) receptorDevDesRow["DeviceDescription"]);
00430         
00431                         /* If this description is in the deviceDescriptionList, add this component
00432                                 to the componentCombo */
00433                         for(unsigned int i=0; i<deviceDescriptionList.size(); ++i){
00434                                 if(deviceDescriptionList[i] == receptorDeviceDesc){
00435                                         unsigned int tmpInsertionPosition = componentCombo->count();
00436         
00437                                         //Add this SIMNOS component to the component combo
00438                                         QString tempComboName ((std::string)simnosRow["Name"] + " [" + (std::string)simnosRow["ComponentID"] + "]");
00439                                         componentCombo->insertItem(tempComboName, tmpInsertionPosition);
00440         
00441                                         //Store the width and length
00442                                         componentWidthMap[tmpInsertionPosition] = Utilities::getUInt((std::string)simnosRow["Width"]);
00443                                         componentLengthMap[tmpInsertionPosition] = Utilities::getUInt((std::string)simnosRow["Length"]);
00444         
00445                                         //Exit from for loop
00446                                         break;
00447                                 }
00448                         }
00449                 }
00450         }
00451     catch (const BadQuery& er) {// Handle any query errors
00452                 cerr<<"LayerPropertiesDialog: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00453                 QString errorString = "Bad query loading SIMNOS components: \"";
00454                 errorString += er.what();
00455                 errorString += "\"";
00456                 QMessageBox::critical( 0, "Device Error", errorString);
00457     }
00458     catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00459         cerr<<"LayerPropertiesDialog: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00460                 QString errorString = "Exception thrown loading SIMNOS components: \"";
00461                 errorString += er.what();
00462                 errorString += "\"";
00463                 QMessageBox::critical( 0, "Device Error", errorString);
00464     }
00465         catch(std::exception& er){// Catch-all for std exceptions
00466                 cerr<<"LayerPropertiesDialog: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00467                 QString errorString = "Exception thrown loading SIMNOS components: \"";
00468                 errorString += er.what();
00469                 errorString += "\"";
00470                 QMessageBox::critical( 0, "Device Error", errorString);
00471         }
00472 
00473         //Indicate if no matching components have been found
00474         if(componentCombo->count() == 0){
00475                 componentCombo->insertItem("No matching components", -1);
00476         }
00477         else{//Signal that content of component combo has changed
00478                 noComponents = false;
00479                 componentComboChanged(componentCombo->currentItem());
00480         }
00481 }
00482 
00483 
00484 /*! Called when the neuron group type is changed and hides and shows
00485         appropriate widgets. */
00486 void LayerPropertiesDialog::neuronGrpTypeChanged(int){
00487         int tempType = NeuronGroupType::getType(neurGrpTypeCombo->currentText());
00488         if(tempType == NeuronGroupType::SIMNOSComponentLayer){
00489                 //Hide neuron spacing widgets
00490                 neuronSpacingText->hide();
00491                 neuronSpacingLabel->hide();
00492 
00493                 //Make width and length non editable
00494                 widthText->setReadOnly(true);
00495                 lengthText->setReadOnly(true);
00496 
00497                 //Show combo with list of input layers to connect to
00498                 inputLayerCombo->show();
00499                 inputLayerLabel->show();
00500 
00501                 //Show combo with list of simnos components
00502                 componentCombo->show();
00503                 componentLabel->show();
00504 
00505                 //Call appropriate slots
00506                 inputLayerComboChanged(inputLayerCombo->currentItem());
00507         }
00508         else{//Should be 2D or 3D rectangular layer
00509                 //Show neuron spacing widgets
00510                 neuronSpacingText->show();
00511                 neuronSpacingLabel->show();
00512 
00513                 //Make width and length editable
00514                 widthText->setReadOnly(false);
00515                 lengthText->setReadOnly(false);
00516                 widthText->clear();
00517                 lengthText->clear();
00518 
00519                 //Hide combo with list of input layers to connect to
00520                 inputLayerCombo->hide();
00521                 inputLayerLabel->hide();
00522 
00523                 //Hide combo with list of simnos components
00524                 componentCombo->hide();
00525                 componentLabel->hide();
00526         }
00527         this->adjustSize();
00528 }
00529 
00530 
00531 /*! This method validates the input from the fields.
00532         If everything is ok, accept() is called.
00533         Otherwise an alert is shown about the missing fields. */
00534 void LayerPropertiesDialog::okButtonPressed(){
00535         QString errorString = "";
00536         try{
00537                 unsigned int tempUInt;
00538                 QString tempS = nameText->text();
00539                 if(tempS == "")
00540                         errorString += "No name specified.\n";
00541                 if(!editMode){//Only check length and width if not in edit mode
00542                         if(lengthText->text() == "")
00543                                 errorString += " No length specified for neuron group.\n";
00544                         else{
00545                                 tempUInt = Utilities::getUInt(lengthText->text().ascii());
00546                                 if(tempUInt < 1)
00547                                         errorString += " Length cannot be less than 1.\n";
00548                         }
00549                         if(widthText->text() == "")
00550                                 errorString += " No width specified for neuron group.\n";
00551                         else{
00552                                 tempUInt = Utilities::getUInt(widthText->text().ascii());
00553                                 if(tempUInt < 1)
00554                                         errorString += " Width cannot be less than 1.\n";
00555                         }
00556                 }
00557                 if(neuronSpacingText->text() == "")
00558                         neuronSpacingText->setText(DEFAULT_NEURON_SPACING);
00559                 tempUInt = Utilities::getUInt(neuronSpacingText->text().ascii());
00560                 if(tempUInt < 1)
00561                         errorString += " Neuron spacing cannot be less than 1.\n";
00562                 tempS = xPosText->text();
00563                 if(tempS == "")
00564                         errorString += " No x position specified.\n";
00565                 tempS = yPosText->text();
00566                 if(tempS == "")
00567                         errorString += " No y position specified.\n";
00568                 tempS = zPosText->text();
00569                 if(tempS == "")
00570                         errorString += " No z position specified.\n";
00571                 
00572                 if(neuronTypeCombo->currentItem() == unknownNeuronTypeIndex){
00573                         errorString += " Cannot select an unrecognized neuron type.\n";
00574                 }
00575         
00576                 if(!editMode){
00577                         if(NeuronGroupType::getType(neurGrpTypeCombo->currentText()) == NeuronGroupType::SIMNOSComponentLayer){
00578                                 if(noInputLayers)
00579                                         errorString += "No device input layer selected\n";
00580                                 if(noComponents)
00581                                         errorString += "No SIMNOS components selected\n";
00582                         }
00583                 }
00584     }
00585     catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00586         cerr<<"LayerPropertiesDialog: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00587                 errorString += "Exception thrown: \"";
00588                 errorString += er.what();
00589                 errorString += "\"";
00590     }
00591 
00592         //Decide whether to accept or reject input
00593         if(errorString != "")
00594                 QMessageBox::critical( this, "Errors", errorString);
00595         else{
00596                 accept();
00597         }
00598 }
00599 
00600 
00601 //---------------------------------------------------------------------
00602 //------------------------ PRIVATE METHODS ----------------------------
00603 //---------------------------------------------------------------------
00604 
00605 /*! Loads up all the available neuron types from the neuron type
00606         database. */
00607 void LayerPropertiesDialog::fillNeurGrpTypeCombo(){
00608         neurGrpTypeCombo->clear();
00609         unsigned short* neurGrpTypeArray = NeuronGroupType::getTypes();
00610         for(int i=0; i<NeuronGroupType::NumberTypes; i++){
00611                 neurGrpTypeCombo->insertItem(NeuronGroupType::getDescription(neurGrpTypeArray[i]));
00612         }
00613 }
00614 
00615 
00616 /*! Loads up a list of all the available input layers. These must match
00617         the width and length of at least one device. */
00618 void LayerPropertiesDialog::loadInputLayers(){
00619         //Clear any existing entries
00620         inputLayerCombo->clear();
00621         noInputLayers = true;
00622 
00623         /* Get a list of neuron groups that match at least one of the width and lengths
00624                 in the Device table*/
00625         try{
00626                 Query networkQuery = networkDBInterface->getQuery();
00627                 networkQuery.reset();
00628                 networkQuery<<"SELECT Name, NeuronGrpID, Width, Length FROM NeuronGroups";
00629                 Result neurGrpResult= networkQuery.store();
00630                 for(Result::iterator resIter = neurGrpResult.begin(); resIter < neurGrpResult.end(); resIter++){
00631                         Row neurGrpRow(*resIter);
00632                         /* Check to see if the width and length of the neuron group
00633                                 match that of any of the rows in the device database */
00634                         unsigned int neurGrpWidth = Utilities::getUInt((std::string)neurGrpRow["Width"]);
00635                         unsigned int neurGrpLength = Utilities::getUInt((std::string)neurGrpRow["Length"]);
00636         
00637                         Query deviceQuery = deviceDBInterface->getQuery();
00638                         deviceQuery.reset();
00639                         deviceQuery<<"SELECT * FROM Devices WHERE TotalNumColumns = "<<neurGrpWidth<<" AND TotalNumRows = "<<neurGrpLength;
00640                         Result deviceResult = deviceQuery.store();
00641                         if(deviceResult.size() > 0){
00642                                 QString neurGrpString((std::string)neurGrpRow["Name"] + " [" += (std::string)neurGrpRow["NeuronGrpID"] += "]");
00643                                 inputLayerCombo->insertItem(neurGrpString, -1);
00644                         }
00645                 }
00646         }
00647     catch (const BadQuery& er) {// Handle any query errors
00648                 cerr<<"LayerPropertiesDialog: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00649                 QString errorString = "Bad query loading input layers: \"";
00650                 errorString += er.what();
00651                 errorString += "\"";
00652                 QMessageBox::critical( 0, "Device Error", errorString);
00653     }
00654     catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00655         cerr<<"LayerPropertiesDialog: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00656                 QString errorString = "Exception thrown loading input layers: \"";
00657                 errorString += er.what();
00658                 errorString += "\"";
00659                 QMessageBox::critical( 0, "Device Error", errorString);
00660     }
00661         catch(std::exception& er){// Catch-all for std exceptions
00662                 cerr<<"LayerPropertiesDialog: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00663                 QString errorString = "Exception thrown loading input layers: \"";
00664                 errorString += er.what();
00665                 errorString += "\"";
00666                 QMessageBox::critical( 0, "Device Error", errorString);
00667         }
00668 
00669         //Add entry specifying that there are no layers matching available devices
00670         if(inputLayerCombo->count() == 0){
00671                 inputLayerCombo->insertItem("No input layers match available devices", -1);
00672         }
00673         else{
00674                 noInputLayers = false;
00675         }
00676 
00677         //Indicate that input layers has changed
00678         inputLayerComboChanged(inputLayerCombo->currentItem());
00679 }
00680 
00681 
00682 

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