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

NetworkDataXmlHandler.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 "NetworkDataXmlHandler.h"
00025 #include "Utilities.h"
00026 #include "Debug.h"
00027 #include "SpikeStreamMainWindow.h"
00028 
00029 //Other includes
00030 #include <iostream>
00031 using namespace std;
00032 
00033 
00034 /*! Constructor. */
00035 NetworkDataXmlHandler::NetworkDataXmlHandler() : QXmlDefaultHandler() {
00036         //Initialise variables
00037         neurSpikeCount = 0;
00038         neurSpikeTotal = 0;
00039 
00040         neuronIDHashMap.set_empty_key(EMPTY_NEURON_ID_KEY);
00041         neuronIDHashMap.set_deleted_key(DELETED_NEURON_ID_KEY);
00042         ArchiveStatistic::neuronIDHashMap = &this->neuronIDHashMap;
00043 }
00044 
00045 
00046 /*! Destructor. */
00047 NetworkDataXmlHandler::~NetworkDataXmlHandler(){
00048         #ifdef MEMORY_DEBUG
00049                 cout<<"DELETING NETWORK DATA XML HANDLER"<<endl;
00050         #endif//MEMORY_DEBUG
00051 }
00052 
00053 
00054 //---------------------------------------------------------------------------------
00055 //---------------------------- PUBLIC METHODS -------------------------------------
00056 //---------------------------------------------------------------------------------
00057 
00058 
00059 /*! Adds a new archive statistic holder. Depending on the type this is added to the.*/
00060         
00061 void NetworkDataXmlHandler::addArchiveStatistics(ArchiveStatisticsHolder* archStatHold){
00062         /* Work through the vector of archive statistics and put them into
00063                 different containers depending on the type.*/
00064         for(vector<ArchiveStatistic*>::iterator iter = archStatHold->archStatVector.begin(); iter != archStatHold->archStatVector.end(); ++iter){
00065                 if((*iter)->getType() == ArchiveStatistic::NEURON_GROUP){
00066                         unsigned int tmpNeurGrpID = ((NeuronGrpArchiveStatistic*)*iter)->getNeuronGrpID();
00067                         neuronGrpStatsMap[tmpNeurGrpID].push_back(*iter);//If there is not a vector entry in the map for this neuron group one should be created.
00068                 }
00069                 else{
00070                         otherArchStatsVector.push_back(*iter);
00071                 }
00072         }
00073 }
00074 
00075 
00076 /*! Deletes an archive statistic holder using the statistics id to find it. */
00077 void NetworkDataXmlHandler::deleteArchiveStatistics(unsigned int statID){
00078         //Track what is going on
00079         int eraseCount = 0;
00080 
00081         //Work through the neuronGrpStatsMap to look for the archive statistic
00082         for(map<unsigned int, vector<ArchiveStatistic*> >::iterator outerIter = neuronGrpStatsMap.begin(); outerIter != neuronGrpStatsMap.end(); ++outerIter){
00083                 //Work through the vector stored at this position in the map
00084                 for(vector<ArchiveStatistic*>::iterator innerIter = outerIter->second.begin(); innerIter != outerIter->second.end(); ++innerIter){
00085                         if( (*innerIter)->getID() == statID ){
00086                                 innerIter = outerIter->second.erase(innerIter);//innerIter now points to the element after the erased element
00087                                 ++eraseCount;
00088                                 if(innerIter == outerIter->second.end())//Don't want to go beyond the end of the vector
00089                                         break;
00090                         }
00091                 }
00092         }
00093         for(vector<ArchiveStatistic*>::iterator iter = otherArchStatsVector.begin(); iter != otherArchStatsVector.end(); ++iter){
00094                 if( (*iter)->getID() == statID ){
00095                         iter = otherArchStatsVector.erase(iter);//iter now points to the element after the erased element
00096                         ++eraseCount;
00097                         if(iter == otherArchStatsVector.end())//Don't want to go beyond the end of the vector
00098                                 break;
00099                 }
00100         }
00101 
00102         //cout<<"NetworkDataXmlHandler: Erased "<<eraseCount<<" ArchiveStatistics."<<endl;
00103 }
00104 
00105 
00106 /*! Returns true if an error has been encountered during parsing. */
00107 bool NetworkDataXmlHandler::getParseError(){
00108         return parseError;
00109 }
00110 
00111 
00112 /*! Returns a string describing the parsing error. */
00113 QString NetworkDataXmlHandler::getParseErrorString(){
00114         return parseErrorString;
00115 }
00116 
00117 
00118 /*! Resets statistics gathered about the archive. */
00119 void NetworkDataXmlHandler::resetStatistics(){
00120         neurSpikeCount  = 0;
00121         neurSpikeTotal = 0;
00122 
00123         //Work through the neuronGrpStatsMap to look for the archive statistic
00124         for(map<unsigned int, vector<ArchiveStatistic*> >::iterator outerIter = neuronGrpStatsMap.begin(); outerIter != neuronGrpStatsMap.end(); ++outerIter){
00125                 //Work through the vector stored at this position in the map
00126                 for(vector<ArchiveStatistic*>::iterator innerIter = outerIter->second.begin(); innerIter != outerIter->second.end(); ++innerIter){
00127                         (*innerIter)->resetFiringNeuronCount();
00128                         (*innerIter)->resetFiringNeuronTotal();
00129                 }
00130         }
00131         for(vector<ArchiveStatistic*>::iterator iter = otherArchStatsVector.begin(); iter != otherArchStatsVector.end(); ++iter){
00132                 (*iter)->resetFiringNeuronCount();
00133                 (*iter)->resetFiringNeuronTotal();
00134         }
00135 }
00136 
00137 
00138 /*! Sets the maps that are updated from the XML file. */
00139 void NetworkDataXmlHandler::setNetworkMonitors(map<unsigned int, NetworkMonitor*> nwMonMap){
00140         networkMonitorMap = nwMonMap;
00141 }
00142 
00143 
00144 //---------------------------------------------------------------------------------
00145 //---------------------------- PROTECTED METHODS ----------------------------------
00146 //---------------------------------------------------------------------------------
00147 
00148 /*! Called when the parser encounters characters. */
00149 bool NetworkDataXmlHandler::characters(const QString& chars){
00150         try{
00151                 unsigned int firingNeuronID = 0;
00152                 if(currentElement == "neuron_group"){
00153                         //Get the list of neurons/ spikes
00154                         QStringList tempStringList = QStringList::split(",", chars);
00155         
00156                         //Add firing neuron IDs to firing neuron maps in this class (for statistics) and elsewhere
00157                         for(unsigned int i=0; i< tempStringList.size(); ++i){
00158                                 firingNeuronID = Utilities::getUInt(tempStringList[i].ascii());
00159 
00160                                 //Store the neuron id for statistical analysis
00161                                 neuronIDHashMap[firingNeuronID] = true;
00162 
00163                                 //Update the neuron group archive statistics
00164                                 for(vector<ArchiveStatistic*>::iterator iter = neuronGrpStatsMap[neuronGrpID].begin(); iter != neuronGrpStatsMap[neuronGrpID].end(); ++iter){
00165                                         (*iter)->recalculateNeuronGrp();
00166                                 }
00167 
00168                                 //Update the graphical representation of the neurons
00169                                 (*networkMonitorMap[neuronGrpID]->bufferMapPointer)[firingNeuronID] = true;//Load neurons into map 2
00170                         }
00171                 }
00172                 else{
00173                         cerr<<"NetworkDataXmlHandler: UNRECOGNIZED ELEMENT"<<endl;
00174                         parseError = true;
00175                         parseErrorString += "Unrecognized element.";
00176                 }
00177         }
00178         catch (std::exception& er) {// Catch-all for std exceptions
00179                 parseError = true;
00180                 parseErrorString += er.what();
00181         }
00182         return true;
00183 }
00184 
00185 
00186 /*! Called when the parser is at the end of an element. */
00187 bool NetworkDataXmlHandler::endElement( const QString&, const QString&, const QString& qName){
00188         if(qName == "neuron_group"){
00189                 //Swap the maps and update the display of the network monitor that has just been changed
00190                 networkMonitorMap[neuronGrpID]->swapMaps();
00191         }
00192         else if(qName == "network_pattern"){//End of the pattern for this timestep
00193                 //Call method to analyse the pattern to measure statistics about it.
00194                 processStatistics();
00195 
00196                 //Inform any listening classes that the statistics have changed.
00197                 SpikeStreamMainWindow::spikeStreamApplication->lock();//Called by separate thread, so need to lock mutex
00198                 emit spikeCountChanged(neurSpikeCount);
00199                 emit spikeTotalChanged(neurSpikeTotal);
00200                 emit statisticsChanged();
00201                 SpikeStreamMainWindow::spikeStreamApplication->unlock();
00202 
00203                 //Empty the hash map containing the neuron ids for this timestep
00204                 neuronIDHashMap.clear();
00205                 
00206         }
00207         return true;
00208 }
00209 
00210 
00211 /*! Called when the parser has an error. */
00212 bool NetworkDataXmlHandler::error ( const QXmlParseException & parseEx ){
00213         cerr<<"NetworkDataXmlHandler: PARSING ERROR: "<<parseEx.message()<<endl;
00214         parseError = true;
00215         parseErrorString += parseEx.message();
00216         return true;
00217 }
00218 
00219 
00220 /*! Called to get the error string for the error. */
00221 QString NetworkDataXmlHandler::errorString (){
00222         return QString("NetworkDataXmlHandler: Default error string");
00223 }
00224 
00225 
00226 /*! Called when the parser has a fatal error. */
00227 bool NetworkDataXmlHandler::fatalError ( const QXmlParseException & parseEx ){
00228         cerr<<"NetworkDataXmlHandler: PARSING FATAL ERROR: "<<parseEx.message()<<endl;
00229         parseError = true;
00230         parseErrorString += parseEx.message();
00231         return true;
00232 }
00233 
00234 
00235 /*! Called when the parser is at the start of the document. */
00236 bool NetworkDataXmlHandler::startDocument(){
00237         neurSpikeCount = 0;
00238 
00239         //Set all of the firing neuron counts to zero
00240         for(vector<ArchiveStatistic*>::iterator iter = otherArchStatsVector.begin(); iter != otherArchStatsVector.end(); ++iter){
00241                 (*iter)->resetFiringNeuronCount();
00242         }
00243         for(map<unsigned int, vector<ArchiveStatistic*> >::iterator outerIter = neuronGrpStatsMap.begin(); outerIter != neuronGrpStatsMap.end(); ++outerIter){
00244                 for(vector<ArchiveStatistic*>::iterator innerIter = outerIter->second.begin(); innerIter != outerIter->second.end(); ++innerIter){
00245                         (*innerIter)->resetFiringNeuronCount();
00246                 }
00247         }
00248 
00249         parseError = false;
00250         parseErrorString = "";
00251         neuronIDHashMap.clear();
00252         return true;
00253 }
00254 
00255 
00256 /*! Called when the parser encounters the start of an XML element. */
00257 bool NetworkDataXmlHandler::startElement(const QString&, const QString&, const QString& qName, const QXmlAttributes& xmlAttributes){
00258         currentElement = qName;
00259         if(qName == "neuron_group"){
00260                 /*Set the neuron group id */
00261                 try{
00262                         bool neuronGrpIDFound = false;
00263                         for(int i=0; i<xmlAttributes.length(); ++i){
00264                                 if(xmlAttributes.localName(i) == "id"){
00265                                         neuronGrpID = Utilities::getUInt(xmlAttributes.value(i).ascii());
00266                                         neuronGrpIDFound = true;
00267                                 }
00268                         }
00269                         if(!neuronGrpIDFound){
00270                                 cerr<<"NetworkDataXmlHandler: Cannot find neuron group ID"<<endl;
00271                                 parseError = true;
00272                                 parseErrorString += "Cannot find neuron group ID.";
00273                         }
00274                 }
00275                 catch (std::exception& er) {// Catch-all for std exceptions
00276                         parseError = true;
00277                         parseErrorString += er.what();
00278                 }
00279         }
00280         return true;
00281 }
00282 
00283 
00284 /*! Called when the parser has a warning. */
00285 bool NetworkDataXmlHandler::warning ( const QXmlParseException & exception ){
00286         cerr<<"NetworkDataXmlHandler: PARSING WARNING: "<<exception.message()<<endl;
00287         return true;
00288 }
00289 
00290 //---------------------------------------------------------------------------------
00291 //-----------------             PRIVATE METHODS                --------------------
00292 //---------------------------------------------------------------------------------
00293 
00294 /*! Gathers statistical information about the archive. Should be called after each 
00295         time step. */
00296 void NetworkDataXmlHandler::processStatistics(){
00297         //Update the ArchiveWidget statistics
00298         neurSpikeCount += neuronIDHashMap.size();//Should add the number of unique ids found in the archive
00299         neurSpikeTotal += neurSpikeCount;
00300 
00301         //Work through the statistical classes that are NOT monitoring a complete neuron group+
00302         for(vector<ArchiveStatistic*>::iterator iter = otherArchStatsVector.begin(); iter != otherArchStatsVector.end(); ++iter){
00303                 (*iter)->recalculate();
00304         }
00305 }
00306 
00307 
00308 

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