link to homepage

Institute for Neuroscience and Medicine

Navigation and service


API documentation

Module.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 "Module.h"
00025 #include "Parameters.h"
00026 #include "SequenceTree.h"
00027 #include "ConcatSequence.h"
00028 #include "Pulse.h"
00029 #include "XMLIO.h"
00030 
00031 /***********************************************************/
00032 Module::Module() {
00033 
00034         m_node          = NULL ;
00035         m_seq_tree      = NULL ;
00036         m_duration      = 0.0  ;
00037         m_calls         = 0    ;
00038 
00039 };
00040 
00041 /***********************************************************/
00042 void            Module::Initialize (DOMNode* node) {
00043 
00044     //if node has no "Name" attribute, insert it and use the node name for its value
00045         string s     = StrX(((DOMElement*) node)->getAttribute (StrX("Name").XMLchar() )).std_str() ;
00046         if (s.empty())
00047                 ((DOMElement*) node)->setAttribute(StrX("Name").XMLchar(),node->getNodeName());
00048 
00049     //set the module name to the node name as well
00050         SetName( StrX(node->getNodeName()).std_str() );
00051 
00052         //set the instances of this node and the sequence tree
00053         m_node       = node;
00054         m_seq_tree   = SequenceTree::instance();
00055         m_parameters = m_seq_tree->GetParameters();
00056 
00057 }
00058 
00059 /***********************************************************/
00060 bool Module::Prepare  (PrepareMode mode){
00061 
00062         ATTRIBUTE("Duration", m_duration);
00063         //ATTRIBUTE("Observe" , NULL);          //special case of observing attributes
00064 
00065         return Prototype::Prepare(mode);
00066 
00067 };
00068 
00069 /***********************************************************/
00070 Module* Module::GetPrototypeByAttributeValue(string name, string attrib) {
00071         return m_seq_tree->GetModuleByAttributeValue(name,attrib);
00072 }
00073 
00074 /***********************************************************/
00075 Module*         Module::GetParent () {
00076 
00077         if (m_seq_tree==NULL || m_node==NULL) return NULL;
00078         return m_seq_tree->GetParent(m_node);
00079 
00080 }
00081 
00082 /***********************************************************/
00083 vector<Module*> Module::GetChildren () {
00084 
00085         if (m_seq_tree==NULL || m_node==NULL) return vector<Module*>() ;
00086         return m_seq_tree->GetChildren(m_node);
00087 
00088 }
00089 
00090 /***********************************************************/
00091 Module*         Module::GetChild (unsigned int position) {
00092 
00093         if (m_seq_tree==NULL || m_node==NULL) return NULL;
00094         return m_seq_tree->GetChild(m_node, position);
00095 
00096 }
00097 
00098 /***********************************************************/
00099 int             Module::GetNumberOfChildren () {
00100 
00101     vector<Module*> vc=GetChildren();
00102     return vc.size();
00103 
00104 };
00105 
00106 /***********************************************************/
00107 bool            Module::InsertChild (string name){
00108 
00109         if ( m_seq_tree==NULL || GetNode()==NULL) return false;
00110 
00111         DOMElement* node = m_seq_tree->GetDOMDocument()->createElement(StrX(name).XMLchar());
00112         if (node==NULL) return false;
00113 
00114         Module* mod = m_seq_tree->GetMPF()->CloneModule(node);
00115         if (mod==NULL)  return false;
00116 
00117         GetNode()->appendChild (node);
00118         m_seq_tree->GetModuleMap()->insert(pair<DOMNode*, Module*> (node, mod));
00119         mod->Initialize(node);
00120 
00121         return true;
00122 
00123 };
00124 
00125 /***********************************************************/
00126 bool            Module::AddDOMattribute    (const string attribute, const string value){
00127 
00128         if (HasDOMattribute(attribute))
00129             return false;
00130 
00131         ((DOMElement*) m_node)->setAttribute( StrX(attribute).XMLchar(), StrX(value).XMLchar() );
00132 
00133         return true;
00134 
00135 };
00136 
00137 /***********************************************************/
00138 void           Module::AddAllDOMattributes (bool show_hidden){
00139 
00140         map<string,Attribute*>::iterator iter;
00141 
00142         for(iter = m_attributes.begin(); iter != m_attributes.end(); iter++) {
00143 
00144                 string attrib_name = iter->first;
00145                 Attribute* attrib = iter->second;
00146 
00147                 //do not take hidden and unobservable attributes into account
00148                 if (!attrib->IsObservable() && !attrib->IsPublic()) continue;
00149                 //mark hidden attributes
00150                 if (!attrib->IsPublic()) attrib_name +="HIDDEN";
00151 
00152                 stringstream sstr;
00153                 if (attrib->IsObservable()) {
00154                         void* p = attrib->GetAddress() ;
00155                         if (attrib->GetTypeID()==typeid(  double*).name()) sstr << (*((double*)   p));
00156                         if (attrib->GetTypeID()==typeid(     int*).name()) sstr << (*((int*)      p));
00157                         if (attrib->GetTypeID()==typeid(    long*).name()) sstr << (*((long*)     p));
00158                         if (attrib->GetTypeID()==typeid(unsigned*).name()) sstr << (*((unsigned*) p));
00159                         if (attrib->GetTypeID()==typeid(    bool*).name()) sstr << (*((bool*)     p));
00160                         if (attrib->GetTypeID()==typeid(  string*).name()) sstr << (*((string*)   p));
00161                 }
00162 
00163                 //some exceptions (ugly): Constants/AnalyticTime in Analytic Pulses, Modules in DelayAtoms, NLG field terms in Gradients
00164                 if ( attrib_name.find("Constant",0) != string::npos && !attrib->IsPublic() ) continue;
00165                 if ( attrib_name.find("Analytic",0) != string::npos && !attrib->IsPublic() ) continue;
00166                 if ( attrib_name.find("Module"  ,0) != string::npos && !attrib->IsPublic() ) continue;
00167                 if ( attrib_name.find("NLG_"    ,0) != string::npos && !attrib->IsPublic() ) continue;
00168 
00169                 AddDOMattribute( attrib_name, sstr.str() );
00170         }
00171 
00172         /*
00173         map<string, void*>::iterator it;
00174 
00175         for( it = m_attrib_addr.begin(); it != m_attrib_addr.end(); it++ ) {
00176 
00177             map<string, bool>::iterator is_obs_attrib = m_attrib_observable.find(it->first);
00178         map<string, bool>::iterator is_xml_attrib = m_attrib_xml.find(it->first);
00179 
00180         if (is_obs_attrib->second) {
00181 
00182                         string attrib_name = it->first;
00183 
00184                         if (!is_xml_attrib->second) {
00185                                 if (!show_hidden) continue;
00186                             attrib_name +="HIDDEN";
00187                         }
00188 
00189                         stringstream sstr;
00190 
00191                         void* p = it->second;
00192                         map<string, string>::iterator type = m_attrib_type.find(it->first);
00193 
00194 
00195                         if (IsDynamic(attrib_name)) {
00196                                 //cout << GetName() << ":" << attrib_name << " is a dynamic attribute:" << endl;
00197                                 AddDOMattribute(attrib_name, "dynamic" );
00198                                 if ( type->second == typeid(double*).name()     ) {
00199                                         pair<multimap< string , double > ::iterator, multimap< string , double > ::iterator> itp;
00200                                         itp = m_record_double.equal_range(attrib_name);
00201                                         multimap< string , double >::iterator it;
00202                                         for (it=itp.first; it!=itp.second; ++it) {
00203                                                 double d=it->second;
00204                                                 if (attrib_name == "InitialPhase") d=fmod(d,360.0);
00205                                                 sstr << d << " ";
00206                                         }
00207                                         AddDOMattribute(attrib_name+"Values", sstr.str() );
00208                                 }
00209                                 if ( type->second == typeid(int*).name()        ) {
00210                                         pair<multimap< string , int > ::iterator, multimap< string , int > ::iterator> itp;
00211                                         itp = m_record_int.equal_range(attrib_name);
00212                                         multimap< string , int >::iterator it;
00213                                         for (it=itp.first; it!=itp.second; ++it) {
00214                                                 sstr << it->second << " ";
00215                                         }
00216                                         AddDOMattribute(attrib_name+"Values", sstr.str() );
00217                                 }
00218                         }
00219                         else {
00220                                 if ( type->second == typeid(double*).name()          ) sstr << (*((double*)       p));
00221                                 if ( type->second == typeid(float*).name()           ) sstr << (*((float*)        p));
00222                                 if ( type->second == typeid(int*).name()             ) sstr << (*((int*)          p));
00223                                 if ( type->second == typeid(unsigned int*).name()) sstr << (*((unsigned int*) p));
00224                                 if ( type->second == typeid(bool*).name()            ) sstr << (*((bool*)         p));
00225                                 if ( type->second == typeid(long*).name()            ) sstr << (*((long*)         p));
00226                                 if ( type->second == typeid(PulseAxis*).name()   ) sstr << (*((int*)          p));
00227                                 if ( type->second == typeid(string*).name()          ) sstr << (*((string*)       p));
00228 
00229                                 if (!show_hidden)
00230                                         if (sstr.str().empty() || sstr.str()=="0")  continue;
00231 
00232                                 AddDOMattribute(attrib_name, sstr.str() );
00233                         }
00234 
00235                 }
00236         }
00237 */
00238 };
00239 
00240 /***********************************************************/
00241 void    Module::DumpTree (string file, Module* mod,int ichild, int level) {
00242 
00243         //root node redirects output buffer, if filename is given
00244         streambuf* sobuf = 0;
00245         std::ofstream* pfout = 0;
00246         if (mod ==NULL) {
00247 
00248             mod=this;
00249 
00250                 if (!file.empty()) {
00251 
00252                         sobuf = cout.rdbuf();                   // Save the original stdout buffer.
00253                         pfout = new ofstream(file.c_str());
00254 
00255                         if (*pfout) cout.rdbuf(pfout->rdbuf()); // Redirect cout output to the opened file.
00256 
00257                 }
00258 
00259         }
00260 
00261         //Dump info on this module
00262         vector<Module*> children = mod->GetChildren();
00263         stringstream spaces_bef;
00264         for (int j=0;j<level;++j) spaces_bef << "  ";
00265         stringstream spaces_aft;
00266         for (int j=level; j<m_seq_tree->GetDepth(); ++j) spaces_aft << "  ";
00267 
00268         if (ichild)     cout    << spaces_bef.str() << "|_ child " << ichild << "   ";
00269         else            cout    << "dump of sequence tree\n"
00270                 << spaces_aft.str() << "                  TYPE              CLASS        NAME  duration      ADCs     TPOIs |  module specific\n"
00271                 << spaces_aft.str() << "                  ----------------------------------------------------------------- |  ---------------\n"
00272                 << "sequence-root";
00273 
00274         for (int j=level; j<m_seq_tree->GetDepth(); ++j) cout << "--";
00275         cout << "> ";
00276 
00277         string class_type = mod->GetClassType();
00278         string name       = mod->GetName();
00279         transform(class_type.begin(), class_type.end(), class_type.begin(), (int(*)(int)) toupper);
00280 
00281         string type;
00282         int    adcs = 0;
00283 
00284         if (mod->GetType() == MOD_CONCAT) {
00285                 type="CONCAT";
00286                 adcs=((Sequence*) mod)->GetNumOfADCs();
00287         }
00288 
00289         if (mod->GetType() == MOD_ATOM) {
00290                 type="ATOM";
00291                 adcs=((Sequence*) mod)->GetNumOfADCs();
00292         }
00293 
00294         if (mod->GetType() == MOD_PULSE) {
00295                 type="PULSE";
00296                 adcs=((Pulse*) mod)->GetNADC() ;
00297         }
00298 
00299         int    tpois = mod->GetNumOfTPOIs();
00300         char chform[70];
00301         sprintf(chform,"%8s %20s %8s %9.3f  %7d  %8d",type.c_str(),class_type.c_str(),name.c_str(),mod->GetDuration(),adcs,tpois);
00302         cout << chform << "  | " << mod->GetInfo() << "\n";
00303 
00304     level++;
00305 
00306     for (unsigned int i=0; i<children.size() ; ++i)
00307         DumpTree(file, mod->GetChild(i),i+1,level);
00308 
00309         // root node restores cout to original state.
00310         if (ichild == 0 && !file.empty() ) {
00311                 cout.rdbuf(sobuf);
00312                 delete pfout;
00313         }
00314 
00315 };
00316 
00317 /***********************************************************/
00318 bool           Module::WriteStaticXML (string xml_file) {
00319 
00320         DOMImplementation* impl =  DOMImplementationRegistry::getDOMImplementation(StrX("Core").XMLchar() );
00321 
00322         if (impl==NULL) return false;
00323 
00324         DOMDocument* doc          = impl->createDocument( 0, StrX("PARAM").XMLchar(), 0);
00325         DOMNode*     topnode      = doc->getFirstChild();
00326     Parameters*  parameters   = m_seq_tree->GetParameters();
00327     DOMNode*     backup_node  = parameters->GetNode();
00328         XMLIO*       xmlio        = new XMLIO();
00329 
00330     parameters->SetNode(topnode);
00331     parameters->AddAllDOMattributes(false);
00332 
00333         if ( ((DOMElement*) topnode)->getAttributeNode(StrX("Name").XMLchar()) != NULL)
00334                 ((DOMElement*) topnode)->removeAttribute (StrX("Name").XMLchar());
00335 
00336     parameters->SetNode(backup_node);
00337 
00338         //recursively add elements
00339         if (!StaticDOM(doc,topnode)) return false;
00340 
00341         xmlio->Write (impl, topnode, xml_file);
00342 
00343         delete doc;
00344         delete topnode;
00345         delete parameters;
00346         delete backup_node;
00347         delete xmlio; 
00348 
00349         return true;
00350 
00351 };
00352 
00353 /***********************************************************/
00354 bool Module::StaticDOM(DOMDocument* doc, DOMNode* node, bool append){
00355         bool ret = true;
00356 /*
00357         DOMNode* backup_node = m_node;
00358 
00359         DOMElement* elem;
00360 
00361 
00362         //trigger the recording of sequence changes through repetition counters
00363         if (GetType() == MOD_CONCAT ) {
00364                 if (append){
00365                         elem = doc->createElement (  StrX("CONCAT").XMLchar() );
00366                         m_node = elem;
00367                         AddAllDOMattributes(false);
00368                         node->appendChild(elem);
00369                     m_node = backup_node;
00370                         if ( ((DOMElement*) elem)->getAttributeNode(StrX("Name").XMLchar()) != NULL)
00371                                 ((DOMElement*) elem)->removeAttribute (StrX("Name").XMLchar());
00372                 }
00373                 ConcatSequence* cs = ((ConcatSequence*) this);
00374                 for (int r=0;r< cs->GetMyRepetitions(); r++) {
00375                         cs->SetRepCounter(r,true);
00376                         vector<Module*> children = GetChildren();
00377                         for (unsigned int j=0; j<children.size() ; ++j) {
00378                                 bool lastrep = (r+1==cs->GetMyRepetitions()) ;
00379                         ret = ( children[j]->StaticDOM(doc, elem, (append && lastrep) ) && ret);
00380                         }
00381                 }
00382                 return ret;
00383         }
00384 
00385         if (!append) return ret;
00386 
00387         string class_type = GetClassType();
00388         transform(class_type.begin(), class_type.end(), class_type.begin(), (int(*)(int)) toupper);
00389 
00390         if (GetType() == MOD_ATOM  )    elem = doc->createElement (  StrX("ATOMIC").XMLchar() );
00391         if (GetType() == MOD_PULSE )    elem = doc->createElement (  StrX("PULSE").XMLchar() );
00392         Module* p = GetParent();
00393 
00394         m_node = elem;
00395 
00396         if (GetType() == MOD_PULSE ){
00397                 string val="";
00398                 if ( class_type == "HARDRFPULSE"      ) val="RF_RECT";
00399                 if ( class_type == "SINCRFPULSE"      ) val="RF_SINC";
00400                 if ( class_type == "GAUSSIANRFPULSE"  ) val="RF_GAUSS";
00401                 if ( class_type == "SECHRFPULSE"      ) val="RF_SECH";
00402                 if ( class_type == "TRAPGRADPULSE"    ) val="GR";
00403                 if ( class_type == "EMPTYPULSE"       ) {
00404                         if ( ( (Pulse*) this)->GetNADC() > 0 )
00405                                 val="RO";
00406                     else
00407                             val="NONE";
00408                         //special case of empty pulses in a variable-length DelayAtom
00409                         string p_class_type = p->GetClassType();
00410                         transform(p_class_type.begin(), p_class_type.end(), p_class_type.begin(), (int(*)(int)) toupper);
00411                         if (p_class_type=="DELAYATOMICSEQUENCE" && p->IsDynamic("Delay")){
00412                                 string dval = StrX(((DOMElement*) node)->getAttribute (StrX("DelayValues").XMLchar())).std_str() ;
00413                                 //cout << GetName() << " " << p_class_type << " " << dval << endl;
00414                                 AddDOMattribute("Duration","dynamic");
00415                                 AddDOMattribute("DurationValues",dval);
00416                                 ((DOMElement*) node)->removeAttribute (StrX("DelayValues").XMLchar());
00417                         }
00418                 }
00419                 //if ( GetClassType() == "") val="";
00420                 AddDOMattribute("Type", val );
00421         }
00422         AddAllDOMattributes(false);
00423 
00424         node->appendChild(elem);
00425 
00426         if ( GetType() == MOD_PULSE && class_type == "EMPTYPULSE" ) {
00427         }
00428 
00429 
00430     m_node = backup_node;
00431 
00432         vector<Module*> children = GetChildren();
00433                 for (unsigned int j=0; j<children.size() ; ++j)
00434                   ret = ( children[j]->StaticDOM(doc, elem) && ret);
00435 
00436         //clean up the XML: remove attributes unnecessary for IDEA
00437         if ( ((DOMElement*) elem)->getAttributeNode(StrX("Name").XMLchar()) != NULL)
00438                 ((DOMElement*) elem)->removeAttribute (StrX("Name").XMLchar());
00439         if (GetType() == MOD_ATOM  ) {
00440                 map<string, void*>::iterator it;
00441                 for( it = m_attrib_addr.begin(); it != m_attrib_addr.end(); it++ ) {
00442                         if ( ((DOMElement*) elem)->getAttributeNode(StrX(it->first).XMLchar()) != NULL)
00443                         ((DOMElement*) elem)->removeAttribute (StrX(it->first).XMLchar());
00444                 }
00445         }
00446 
00447 
00448 */
00449         return ret;
00450 };
00451 

Servicemeu

institutes

Scientific Technical Facilities