Hi all,

I have been thinking about the best way to map between variables in a model and variables in code generated from the model (or more precisely the mapping between variables in a model and results from numerical simulation of the model using the code generated by the CCGS). The typical way to do anything with a particular variable in a model is via the variable's cmeta:id (i.e., graph metadata).

Using the current CCGS implementation it is fairly easy to grab the original CellML variable object for each variable in the generated code and from that you can get the variable's cmeta:id. However, the problem is that there can be multiple variables in a model which resolve to the same underlying variable in the generated code. Thus, when trying to use a particular variable from a model via its cmeta:id it may not appear directly in the code, and hence the simulation result data.

One way to get all the variables in a model which link to a given variable in the generated code is to simply search the model looking at connections and source variables, etc. to determine this information. An alternate method is to provide this information directly via the CCGS - which internally handles all model connections in a more efficient manner.

Following up on this I have modified the CCGS to provide a method on the CCodeVariable object/interface which provides a character array containing a comma separated list of all the cmeta:id's which are linked to each code variable (see attached patch for current trunk source). For me this works quite well and provides a means to describe in the generated code all the variables in a model which are linked to a given variable/array index in the generated code.

I'm sure the actual implementation is pretty bad, but the general idea seems sound to me. What do people think? Perhaps there is already a way to do this or something similar, but I couldn't find it. Or maybe I'm just going about this in completely the wrong way?


David.

--
David Nickerson, PhD
Research Fellow
Division of Bioengineering
Faculty of Engineering
National University of Singapore
Email: [EMAIL PROTECTED]
Index: CCGS/sources/CCGSGenerator.cpp
===================================================================
--- CCGS/sources/CCGSGenerator.cpp	(revision 1014)
+++ CCGS/sources/CCGSGenerator.cpp	(working copy)
@@ -993,7 +993,7 @@
       (new CDA_CCodeVariable
        ((*i)->GetSourceVariable(), (*i)->GetIndex(),
         ((*i)->GetArray() == VariableInformation::DEPENDENT_AND_RATE),
-        (*i)->GetDegree(), type
+        (*i)->GetDegree(), type, (*i)->GetIDString()
         ));
   }
 }
Index: CCGS/sources/VariableConnections.cpp
===================================================================
--- CCGS/sources/VariableConnections.cpp	(revision 1014)
+++ CCGS/sources/VariableConnections.cpp	(working copy)
@@ -302,7 +302,17 @@
         aMsg += (*i).second->getSource()->GetName();
         throw CodeGenerationError(aMsg);
       }
+      
+      /* Append the ID */
+      vi->AppendID(var);
 
+      /* ANDRE
+      RETURN_INTO_WSTRING(vn,var->name());
+      printf("variable and source \"%S\"\n",vn.c_str());
+      std::wstring fred = vi->GetIDString();
+      printf("  ID string = \"%S\"\n",fred.c_str());
+      */
+
       (*i).second->setSource(vi);
 
       // Set the annotation...
@@ -338,6 +348,17 @@
     RETURN_INTO_OBJREF(vi, VariableInformation,
                        new VariableInformation(var, varinfoKey, source));
 
+    /* Append the ID */
+    vi->AppendID(var);
+
+    /* ANDRE
+    RETURN_INTO_WSTRING(vn,var->name());
+    std::wstring sn = source->GetName();
+    printf("variable \"%S\" has source \"%S\"\n",vn.c_str(),sn.c_str());
+    std::wstring fred = vi->GetIDString();
+    printf("  ID string = \"%S\"\n",fred.c_str());
+    */
+    
     // Set the annotation...
     annot.addAnnotation(vi);
 
Index: CCGS/sources/CCGSImplementation.hpp
===================================================================
--- CCGS/sources/CCGSImplementation.hpp	(revision 1014)
+++ CCGS/sources/CCGSImplementation.hpp	(working copy)
@@ -144,11 +144,11 @@
    iface::cellml_api::CellMLVariable* aVar, uint32_t aVariableIndex=0,
    bool aHasDifferential=false, uint32_t aDerivative=0,
    iface::cellml_services::VariableEvaluationType aType=
-   iface::cellml_services::COMPUTED
+   iface::cellml_services::COMPUTED, const wchar_t* idString=NULL
   )
     : _cda_refcount(1), mVar(aVar), mVariableIndex(aVariableIndex),
       mHasDifferential(aHasDifferential), mDerivative(aDerivative),
-      mType(aType)
+      mType(aType), mIDString(idString)
   {
     mVar->add_ref();
   }
@@ -189,12 +189,28 @@
     return mVar;
   }
 
+  char* ids()
+    throw (std::exception&)
+  {
+    const wchar_t* str = mIDString.c_str();
+    size_t len = wcsrtombs(NULL,&str,0,NULL);
+    if (len > 0)
+    {
+      len++;
+      char* s = (char*)malloc(len);
+      wcsrtombs(s,&str,len,NULL);
+      return(s);
+    }
+    return((char*)NULL);
+  }
+
 private:
   iface::cellml_api::CellMLVariable* mVar;
   uint32_t mVariableIndex;
   bool mHasDifferential;
   uint32_t mDerivative;
   iface::cellml_services::VariableEvaluationType mType;
+  std::wstring mIDString;
 };
 
 class CDA_CCodeVariableIterator
Index: CCGS/sources/Variables.hxx
===================================================================
--- CCGS/sources/Variables.hxx	(revision 1014)
+++ CCGS/sources/Variables.hxx	(working copy)
@@ -12,7 +12,7 @@
   VariableInformation(iface::cellml_api::CellMLVariable* aSourceVariable,
                       TemporaryAnnotationKey& aKey)
     : TemporaryAnnotation(aSourceVariable, aKey), mSource(aSourceVariable),
-      mFlags(0), mDegree(1), mSourceInformation(NULL)
+      mFlags(0), mDegree(1), mIDString(), mSourceInformation(NULL)
   {
     wchar_t* tmp = aSourceVariable->name();
     mName = tmp;
@@ -131,12 +131,61 @@
       return mSource;
   }
 
+  /* Andre Hack */
+  void AppendID(iface::cellml_api::CellMLVariable* aVar)
+  {
+    if (mSourceInformation)
+      mSourceInformation->AppendID(aVar);
+    else
+    {
+      /* Does the variable have a cmeta:id? */
+      RETURN_INTO_WSTRING(id,aVar->cmetaId());
+      if (id.length() > 0)
+      {
+        iface::cellml_api::Model* model = aVar->modelElement();
+        iface::cellml_api::URI* uri = model->base_uri();
+        RETURN_INTO_WSTRING(uriS,uri->asText());
+        uriS.append(L"#");
+        uriS.append(id);
+        if (mIDString.length() > 0) mIDString.append(L",");
+        mIDString.append(uriS);
+        uri->release_ref();
+        model->release_ref();
+      }
+    }
+  }
+  const wchar_t* GetIDString()
+  {
+    if (mSourceInformation)
+      return mSourceInformation->GetIDString();
+    else
+      return mIDString.c_str();
+  }
+
+#if defined ANDRES_BAD_HACK
+  void SetVariable(iface::cellml_api::CellMLVariable* aVar)
+  {
+    mCellMLElement = aVar;
+  }
+  
+  iface::cellml_api::CellMLVariable* GetVariable()
+  {
+    if (mSourceInformation)
+      return mSourceInformation->GetVariable();
+    else if (mCellMLElement) return 
+      dynamic_cast<iface::cellml_api::CellMLVariable*>
+      (mCellMLElement.getPointer());
+    return NULL;
+  }
+#endif
+
   const wchar_t* GetName() { return mName.c_str(); }
 private:
   iface::cellml_api::CellMLVariable* mSource;
   double mInitialValue;
   uint32_t mFlags, mDegree, mIndex;
   std::wstring mName;
+  std::wstring mIDString;
   uint32_t mArrayType;
   VariableInformation* mSourceInformation;
 };
Index: interfaces/CCGS.idl
===================================================================
--- interfaces/CCGS.idl	(revision 1014)
+++ interfaces/CCGS.idl	(working copy)
@@ -80,6 +80,12 @@
      * The CellML variable element of the source (no in interfaces).
      */
     readonly attribute cellml_api::CellMLVariable source;
+
+    /* Andre's hack */
+    /**
+     * The list of (absolute) IDs referencing this variable.
+     */
+    readonly attribute string ids;
   };
 #pragma terminal-interface
 
_______________________________________________
cellml-discussion mailing list
cellml-discussion@cellml.org
http://www.cellml.org/mailman/listinfo/cellml-discussion

Reply via email to