link to homepage

Institute for Neuroscience and Medicine

Navigation and service


API documentation

SequenceTree.cpp

Go to the documentation of this file.
00001 
00005 /*
00006  *  JEMRIS Copyright (C) 2007-2010  Tony Stöcker, Kaveh Vahedipour
00007  *                                  Forschungszentrum Jülich, Germany
00008  *
00009  *  This program is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  This program is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with this program; if not, write to the Free Software
00021  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  */
00023 
00024 #include "SequenceTree.h"
00025 #include "Module.h"
00026 #include "World.h"
00027 #include "Parameters.h"
00028 #include "ConcatSequence.h"
00029 #include "AtomicSequence.h"
00030 #include "Pulse.h"
00031 #include "XMLIO.h"
00032 
00033 SequenceTree*            SequenceTree::m_instance = 0;
00034 
00035 /***********************************************************/
00036 SequenceTree::SequenceTree() {
00037 
00038         m_dom_doc    = 0;
00039         m_parameters = 0;
00040         m_root_seq   = 0;
00041         m_state      = false;
00042         m_depth      = 0;
00043         m_mpf        = new ModulePrototypeFactory();
00044         m_xio        = new XMLIO();
00045 
00046 }
00047 
00048 /***********************************************************/
00049 SequenceTree::~SequenceTree() {
00050 
00051         SequenceTree::m_instance = 0;
00052 
00053         delete m_xio;
00054 
00055         XMLPlatformUtils::Terminate();
00056 
00057         // Delete all Modules, except the Parameters singleton
00058         map<DOMNode*,Module*>::iterator iter;
00059         for (iter = m_Modules.begin(); iter != m_Modules.end(); iter++ )
00060                 if (m_parameters != iter->second)
00061                         delete iter->second;
00062 
00063         // Delete the factory (deletes the Parameters singleton!)
00064         delete m_mpf;
00065 
00066 }
00067 
00068 /***********************************************************/
00069 SequenceTree* SequenceTree::instance() {
00070 
00071     if(m_instance == 0)
00072         m_instance = new SequenceTree();
00073 
00074     return m_instance;
00075 
00076 }
00077 
00078 /***********************************************************/
00079 void SequenceTree::Initialize(string seqFile) {
00080 
00081     //initialize
00082         m_state   = false;
00083         m_dom_doc = m_xio->Parse(seqFile);
00084 
00085         DOMNode* topnode;
00086 
00087         if (!(topnode = m_dom_doc->getFirstChild()))
00088             return;
00089 
00090         m_state   = ( StrX(topnode->getNodeName()).std_str() == "Parameters");
00091 
00092 }
00093 
00094 /***********************************************************/
00095 DOMNode*            SequenceTree::GetParentNode (DOMNode*     node) {
00096 
00097     return node->getParentNode();
00098 
00099 }
00100 
00101 /***********************************************************/
00102 DOMNodeList*        SequenceTree::GetChildNodes (DOMNode*     node) {
00103 
00104     return node->getChildNodes();
00105 
00106 }
00107 
00108 /***********************************************************/
00109 DOMNamedNodeMap*    SequenceTree::GetAttributes (DOMNode*     node) {
00110     return node->getAttributes();
00111 }
00112 
00113 /***********************************************************/
00114 Module*             SequenceTree::GetModule    (DOMNode*     node) {
00115 
00116         map<DOMNode*,Module*>::iterator iter = m_Modules.find(node);
00117 
00118         if( iter != m_Modules.end() )
00119             return ( iter->second );
00120 
00121         return NULL;
00122 
00123 }
00124 
00125 /***********************************************************/
00126 unsigned int        SequenceTree::AddModule    (string       name) {
00127 
00128     unsigned int id = 0;
00129     return id;
00130 
00131 }
00132 
00133 /***********************************************************/
00134 unsigned int        SequenceTree::Populate     ()  {
00135 
00136         DOMNode* topnode;
00137         if (!(topnode = m_dom_doc->getFirstChild())) return EMPTY_DOCUMENT;
00138 
00139         //Prepare the parameters first! (if any specified in XML)
00140         DOMNodeList* dnl = m_dom_doc->getElementsByTagName( StrX("Parameters").XMLchar() );
00141         if (dnl->getLength() > 0) {
00142 
00143                 m_parameters = Parameters::instance();
00144                 SequenceTree::CreateModule(this,dnl->item(0));
00145                 m_parameters->Prepare(PREP_INIT);
00146                 m_parameters->Prepare(PREP_VERBOSE);
00147 
00148                 if (dnl->getLength() > 1)
00149                         cout << "Warning: multiple tags 'Parameters' in XML." << endl;
00150 
00151         }
00152 
00153         //populate
00154         m_depth = 0;
00155         RunTree(topnode, this, &SequenceTree::CreateModule);
00156         m_depth--;
00157         //find top node of the sequence tree
00158         ConcatSequence* m_root_seq = GetRootConcatSequence();
00159 
00160         //run Prepare() twice to solve all module cross-dependencies (silent)
00161         m_root_seq->Prepare(PREP_INIT);
00162         m_root_seq->Prepare(PREP_INIT);
00163         m_root_seq->Prepare(PREP_INIT);
00164 
00165         //prep. static atom, if exists
00166         World* pW = World::instance();
00167         if (pW->pStaticAtom != NULL)
00168         {
00169                 double d = m_root_seq->GetDuration();
00170                 vector<Module*> children = pW->pStaticAtom->GetChildren();
00171                 pW->pStaticAtom->Prepare(PREP_INIT);
00172                 pW->pStaticAtom->Prepare(PREP_INIT);
00173                 for (unsigned int j=0; j<children.size() ; ++j)
00174                         ((Pulse*) children[j])->SetDuration(d);
00175                 //cout << children.size() << " " << pW->pStaticAtom->GetDuration() << " XX\n";
00176         }
00177 
00178         //check name consistency
00179         map<DOMNode*,Module*>::iterator iter1;
00180         map<DOMNode*,Module*>::iterator iter2;
00181 
00182         for (iter1 = m_Modules.begin(); iter1!=m_Modules.end(); iter1++ )
00183           for (iter2 = iter1,iter2++; iter2!=m_Modules.end(); iter2++ )
00184                 if ( (iter1->second)->GetName() == (iter2->second)->GetName() )
00185                         cout    << "SequenceTree::Populate warning: 2 modules with equal names exist: '"
00186                                 <<  (iter1->second)->GetName() << "'. Class types: ("
00187                                 <<  (iter1->second)->GetClassType() << "," <<  (iter2->second)->GetClassType() << ")" << endl;
00188 
00189         //verbose Prepare call : errors have to be reported
00190         m_root_seq->Prepare(PREP_VERBOSE);
00191 
00192         return OK;
00193 
00194 }
00195 
00196 /***********************************************************/
00197 int        SequenceTree::RunTree (DOMNode* node, void* ptr, unsigned int (*fun) (void*, DOMNode*) ,int depth ) {
00198 
00199         DOMNode* child;
00200 
00201         if (node) {
00202 
00203                 if (node->getNodeType() == DOMNode::ELEMENT_NODE) {
00204 
00205                         string s = StrX(node->getNodeName()).std_str() ;
00206 
00207                         if ( s != "Parameters" ) {
00208                                 unsigned int code = fun(ptr,node);
00209                                 if (code>0) return depth;
00210                         }
00211 
00212                         depth++;
00213                         m_depth = (depth>m_depth?depth:m_depth);
00214 
00215                         for (child = node->getFirstChild(); child != 0; child=child->getNextSibling())
00216                         {
00217                                 RunTree(child,ptr,fun,depth);
00218                                 if (s == "Parameters" && StrX(child->getNodeName()).std_str() == "AtomicSequence" )
00219                                 {
00220                                         DOMNodeList* dnl = m_dom_doc->getElementsByTagName( StrX("AtomicSequence").XMLchar() );
00221                                         AtomicSequence* A = ((AtomicSequence*) m_Modules.find(dnl->item(dnl->getLength()-1))->second);
00222                                         World* pW = World::instance();
00223                                         pW->pStaticAtom = A;
00224                                 }
00225                         }
00226                 }
00227         }
00228 
00229         return depth;
00230 
00231 }
00232 
00233 /***********************************************************/
00234 unsigned int SequenceTree::CreateModule(void* ptr,DOMNode* node){
00235 
00236         SequenceTree* ST = (SequenceTree*) ptr;
00237         Module* module   = ST->m_mpf->CloneModule(node);
00238 
00239         if (!module)
00240             return 1;
00241 
00242         ST->m_Modules.insert(pair<DOMNode*, Module*> (node, module));
00243         module->Initialize(node);
00244 
00245         return OK;
00246 
00247 }
00248 
00249 /***********************************************************/
00250 Module*               SequenceTree::GetParent    (DOMNode* node)         {
00251 
00252         DOMNode* parent = node->getParentNode();
00253 
00254         if (!parent)
00255                 return NULL;
00256 
00257         return m_Modules.find(parent)->second;
00258 
00259 }
00260 
00261 /***********************************************************/
00262 vector<Module*>       SequenceTree::GetChildren  (DOMNode* node)         {
00263 
00264         vector<Module*> children;
00265 
00266         DOMNodeList* dnl = node->getChildNodes();
00267 
00268         for (unsigned int i = 0; i < dnl->getLength(); i++) {
00269                 if (dnl->item(i)->getNodeType() == DOMNode::ELEMENT_NODE)
00270                         children.push_back( m_Modules.find(dnl->item(i))->second );
00271         }
00272 
00273         return children;
00274 
00275 }
00276 
00277 
00278 /***********************************************************/
00279 Module*               SequenceTree::GetChild     (DOMNode* node, unsigned int position) {
00280 
00281         vector<Module*> children = GetChildren(node);
00282         return children.at(position);
00283 
00284 }
00285 
00286 
00287 /***********************************************************/
00288 ConcatSequence*               SequenceTree::GetRootConcatSequence() {
00289 
00290         DOMNodeList* dnl = m_dom_doc->getElementsByTagName( StrX("ConcatSequence").XMLchar() );
00291         return ((ConcatSequence*) m_Modules.find(dnl->item(0))->second);
00292 
00293 }
00294 
00295 /***********************************************************/
00296 Module* SequenceTree::GetModuleByAttributeValue  (string name, string value) {
00297 
00298     map<DOMNode*, Module*>::iterator itmod;
00299 
00300     for( itmod = m_Modules.begin(); itmod != m_Modules.end(); itmod++ )
00301         if ( value == StrX(((DOMElement*) itmod->first )->getAttribute (StrX(name).XMLchar())).std_str() )
00302             return itmod->second;
00303 
00304     return NULL;
00305 
00306 }
00307 
00308 /***********************************************************/
00309 void          SequenceTree::SerializeModules(string xml_file){
00310 
00311         DOMImplementation* impl    =  DOMImplementationRegistry::getDOMImplementation(StrX("Core").XMLchar() );
00312 
00313         if (impl==NULL) return;
00314 
00315         DOMDocument* docbackup =  m_dom_doc;
00316         DOMDocument* doc       =  impl->createDocument( 0, StrX("JEMRIS_MODULES").XMLchar(), 0);
00317         m_dom_doc              = doc;
00318         DOMNode*     topnode   = doc->getFirstChild();
00319 
00320         DOMElement* concats    = doc->createElement (  StrX("CONCATS").XMLchar() );
00321         DOMElement* atoms      = doc->createElement (  StrX("ATOMS"  ).XMLchar() );
00322         DOMElement* pulses     = doc->createElement (  StrX("PULSES" ).XMLchar() );
00323 
00324         topnode->appendChild(concats);
00325         topnode->appendChild(atoms);
00326         topnode->appendChild(pulses);
00327 
00328         map<string, Module*>* ModList = m_mpf->GetModuleList();
00329         map<string, Module*>::iterator itmod;
00330 
00331         for(itmod = ModList->begin(); itmod != ModList->end(); itmod++) {
00332 
00333                 string module_name = itmod->first;
00334                 DOMElement* node   = doc->createElement ( StrX(module_name).XMLchar() );
00335                 Module* module     = m_mpf->CloneModule(node);
00336 
00337                 module->Initialize(node);
00338                 module->Prepare(PREP_INIT);
00339 
00340                 //if any automatically added children, remove them
00341                 for (int i=0;i<module->GetNumberOfChildren(); i++)
00342                         node->removeChild(module->GetChild(i)->GetNode());
00343 
00344                 module->AddAllDOMattributes();
00345 
00346                 if (module->GetType() == MOD_CONCAT) concats->appendChild(node);
00347                 if (module->GetType() == MOD_ATOM  )   atoms->appendChild(node);
00348                 if (module->GetType() == MOD_PULSE )  pulses->appendChild(node);
00349                 if (module->GetType() == MOD_VOID  ) topnode->appendChild(node);
00350 
00351                 cout << module->GetClassType() << endl;
00352         }
00353 
00354         XMLIO xio;
00355         xio.Write(impl, doc->getDocumentElement(), xml_file);
00356 
00357         m_dom_doc = docbackup;
00358 
00359 }

Servicemeu

institutes

Scientific Technical Facilities