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