Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

export enumeration definition to ssp #1266

Merged
merged 4 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/OMSimulatorLib/Component.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ namespace oms
virtual oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const = 0;
virtual oms_status_enu_t exportToSSV(pugi::xml_node& ssvNode) { return logError_NotImplemented; }
virtual void getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& unitDefinitions) { return ; }
virtual void getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions) { return ; }

virtual oms_status_enu_t initialize() = 0;
virtual oms_status_enu_t instantiate() = 0;
Expand Down
20 changes: 20 additions & 0 deletions src/OMSimulatorLib/ComponentFMUCS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ oms::Component* oms::ComponentFMUCS::NewComponent(const oms::ComRef& cref, oms::
std::string unitName = component->values.getUnitFromModeldescription(connectorCref);
if (!unitName.empty())
connector->connectorUnits[unitName] = component->values.modeldescriptionUnitDefinitions[unitName];

// get enumerationTypes
std::string enumType = component->values.getEnumerationTypeFromModeldescription(connectorCref);
if (!enumType.empty())
connector->enumerationName[connectorCref] = enumType;
}
}

Expand Down Expand Up @@ -304,6 +309,16 @@ oms::Component* oms::ComponentFMUCS::NewComponent(const pugi::xml_node& node, om
if (!unitName.empty())
component->connectors.back()->connectorUnits[unitName] = component->values.modeldescriptionUnitDefinitions[unitName];
}
// set enumeration definitions
if ((*itConnectors).child(oms::ssp::Version1_0::ssc::enumeration_type))
{
std::string enumTypeName = (*itConnectors).child(oms::ssp::Version1_0::ssc::enumeration_type).attribute("name").as_string();
if (!enumTypeName.empty())
component->connectors.back()->enumerationName[component->connectors.back()->getName().c_str()] = enumTypeName;

// give priority to enum definitions in ssd over modeldescription.xml, it is possible the user might have manually change values in ssd file
component->values.importEnumerationDefinitions(ssdNode, enumTypeName);
}
}
}
else if(name == oms::ssp::Draft20180219::ssd::element_geometry)
Expand Down Expand Up @@ -389,6 +404,11 @@ void oms::ComponentFMUCS::getFilteredUnitDefinitionsToSSD(std::map<std::string,
return values.getFilteredUnitDefinitionsToSSD(unitDefinitions);
}

void oms::ComponentFMUCS::getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions)
{
return values.getFilteredEnumerationDefinitionsToSSD(enumerationDefinitions);
}

oms_status_enu_t oms::ComponentFMUCS::exportToSSV(pugi::xml_node& ssvNode)
{
return values.exportToSSV(ssvNode);
Expand Down
1 change: 1 addition & 0 deletions src/OMSimulatorLib/ComponentFMUCS.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ namespace oms
oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const;
oms_status_enu_t exportToSSV(pugi::xml_node& ssvNode);
void getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& unitDefinitions);
void getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions);
oms_status_enu_t exportToSSVTemplate(pugi::xml_node& ssvNode, Snapshot& snapshot);
oms_status_enu_t exportToSSMTemplate(pugi::xml_node& ssmNode);
oms_status_enu_t instantiate();
Expand Down
20 changes: 20 additions & 0 deletions src/OMSimulatorLib/ComponentFMUME.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ oms::Component* oms::ComponentFMUME::NewComponent(const oms::ComRef& cref, oms::
std::string unitName = component->values.getUnitFromModeldescription(connectorCref);
if (!unitName.empty())
connector->connectorUnits[unitName] = component->values.modeldescriptionUnitDefinitions[unitName];

// get enumerationTypes
std::string enumType = component->values.getEnumerationTypeFromModeldescription(connectorCref);
if (!enumType.empty())
connector->enumerationName[connectorCref] = enumType;
}
}

Expand Down Expand Up @@ -302,6 +307,16 @@ oms::Component* oms::ComponentFMUME::NewComponent(const pugi::xml_node& node, om
if (!unitName.empty())
component->connectors.back()->connectorUnits[unitName] = component->values.modeldescriptionUnitDefinitions[unitName];
}
// set enumeration definitions
if ((*itConnectors).child(oms::ssp::Version1_0::ssc::enumeration_type))
{
std::string enumTypeName = (*itConnectors).child(oms::ssp::Version1_0::ssc::enumeration_type).attribute("name").as_string();
if (!enumTypeName.empty())
component->connectors.back()->enumerationName[component->connectors.back()->getName().c_str()] = enumTypeName;

// give priority to enum definitions in ssd over modeldescription.xml
component->values.importEnumerationDefinitions(ssdNode, enumTypeName);
}
}
}
else if(name == oms::ssp::Draft20180219::ssd::element_geometry)
Expand Down Expand Up @@ -387,6 +402,11 @@ void oms::ComponentFMUME::getFilteredUnitDefinitionsToSSD(std::map<std::string,
return values.getFilteredUnitDefinitionsToSSD(unitDefinitions);
}

void oms::ComponentFMUME::getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions)
{
return values.getFilteredEnumerationDefinitionsToSSD(enumerationDefinitions);
}

oms_status_enu_t oms::ComponentFMUME::exportToSSV(pugi::xml_node& ssvNode)
{
return values.exportToSSV(ssvNode);
Expand Down
1 change: 1 addition & 0 deletions src/OMSimulatorLib/ComponentFMUME.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ namespace oms
oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const;
oms_status_enu_t exportToSSV(pugi::xml_node& ssvNode);
void getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& unitDefinitions);
void getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions);
oms_status_enu_t exportToSSVTemplate(pugi::xml_node& ssvNode, Snapshot& snapshot);
oms_status_enu_t exportToSSMTemplate(pugi::xml_node& ssmNode);
oms_status_enu_t instantiate();
Expand Down
2 changes: 2 additions & 0 deletions src/OMSimulatorLib/Connector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ oms_status_enu_t oms::Connector::exportToSSD(pugi::xml_node &root) const
break;
case oms_signal_type_enum:
node.append_child(oms::ssp::Version1_0::ssc::enumeration_type);
for (const auto & it : this->enumerationName)
node.child(oms::ssp::Version1_0::ssc::enumeration_type).append_attribute("name") = it.second.c_str();
break;
case oms_signal_type_integer:
node.append_child(oms::ssp::Version1_0::ssc::integer_type);
Expand Down
1 change: 1 addition & 0 deletions src/OMSimulatorLib/Connector.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ namespace oms
void setGeometry(const oms::ssd::ConnectorGeometry* newGeometry);

std::map<std::string, std::map<std::string, std::string>> connectorUnits; ///< single entry map which contains unit as key and BaseUnits as value for a connector
std::map<std::string, std::string> enumerationName; ///< single entry map which contains connector name as key and enumerationName as value for a connector of type ssc:Enumeration

const oms_causality_enu_t getCausality() const {return causality;}
const oms_signal_type_enu_t getType() const {return type;}
Expand Down
34 changes: 33 additions & 1 deletion src/OMSimulatorLib/Model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ oms_status_enu_t oms::Model::exportToSSD(Snapshot& snapshot) const
if (oms_status_ok != system->exportToSSD(system_node, snapshot, this->variantName))
return logError("export of system failed");
}

exportEnumerationDefinitionsToSSD(ssdNode);
exportUnitDefinitionsToSSD(ssdNode);

pugi::xml_node default_experiment = ssdNode.append_child(oms::ssp::Draft20180219::ssd::default_experiment);
Expand Down Expand Up @@ -890,6 +890,10 @@ oms_status_enu_t oms::Model::importFromSnapshot(const Snapshot& snapshot)
{
// allow importing unitDefinitions, the unitDefinitions are handled in Values.cpp importFromSnapshot
}
else if (name == oms::ssp::Draft20180219::ssd::enumerations)
{
// allow importing enumerations, the enumerationDefinitions are handled in Values.cpp importFromSnapshot
}
else if (name == oms::ssp::Draft20180219::ssd::default_experiment)
{
startTime = it->attribute("startTime").as_double(0.0);
Expand Down Expand Up @@ -1520,6 +1524,34 @@ void oms::Model::exportUnitDefinitionsToSSD(pugi::xml_node& node) const
}
}

void oms::Model::exportEnumerationDefinitionsToSSD(pugi::xml_node& node) const
{
if (!system)
return;

std::map<std::string, std::map<std::string, std::string>> enumerationDefinitions;
for (const auto& component : system->getComponents())
component.second->getFilteredEnumerationDefinitionsToSSD(enumerationDefinitions);

if (enumerationDefinitions.empty())
return;

pugi::xml_node node_enumeration = node.append_child(oms::ssp::Draft20180219::ssd::enumerations);

for (const auto &it : enumerationDefinitions)
{
pugi::xml_node ssc_enumeration = node_enumeration.append_child(oms::ssp::Version1_0::ssc::enumeration_type);
ssc_enumeration.append_attribute("name") = it.first.c_str();
for (const auto & item: it.second)
{
pugi::xml_node enumItem = ssc_enumeration.append_child(oms::ssp::Version1_0::ssc::enum_item);
enumItem.append_attribute("name") = item.first.c_str();
enumItem.append_attribute("value") = item.second.c_str();
}
}

}

oms_status_enu_t oms::Model::importSignalFilter(const std::string& filename, const Snapshot& snapshot)
{
if (".*" == filename) // avoid error messages for older ssp files
Expand Down
1 change: 1 addition & 0 deletions src/OMSimulatorLib/Model.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ namespace oms
oms_status_enu_t exportSSMTemplate(const ComRef& cref, const std::string& filename);
void exportSignalFilter(Snapshot& snapshot) const;
void exportUnitDefinitionsToSSD(pugi::xml_node& node) const;
void exportEnumerationDefinitionsToSSD(pugi::xml_node& node) const;
oms_status_enu_t importFromSnapshot(const Snapshot& snapshot);
oms_status_enu_t importSnapshot(const char* snapshot, char** newCref);
oms_status_enu_t importSignalFilter(const std::string& filename, const Snapshot& snapshot);
Expand Down
65 changes: 65 additions & 0 deletions src/OMSimulatorLib/Values.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,19 @@ void oms::Values::getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map
}
}

void oms::Values::getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions)
{
if (modeldescriptionTypeDefinitions.empty())
return;

for(const auto &it: modeldescriptionTypeDefinitions)
{
auto enumType = enumerationDefinitions.find(it.first);
if (enumType == enumerationDefinitions.end())
enumerationDefinitions[it.first] = it.second;
}
}

oms_status_enu_t oms::Values::setInteger(const ComRef& cref, int value)
{
integerStartValues[cref] = value;
Expand Down Expand Up @@ -575,6 +588,16 @@ std::string oms::Values::getUnitFromModeldescription(ComRef& cref) const
return "";
}

std::string oms::Values::getEnumerationTypeFromModeldescription(ComRef& cref) const
{
// search in modelDescription.xml
auto enumType = modeldescriptionEnumeration.find(cref);
if (enumType != modeldescriptionEnumeration.end())
return enumType->second;

return "";
}

oms_status_enu_t oms::Values::getIntegerFromModeldescription(const ComRef& cref, int& value)
{
// search in modelDescription.xml
Expand Down Expand Up @@ -1486,6 +1509,29 @@ void oms::Values::importUnitDefinitions(const pugi::xml_node& node)
}
}

void oms::Values::importEnumerationDefinitions(const pugi::xml_node& node, std::string& enumTypename)
{

if (!node)
return;

pugi::xml_node enumeration = node.child(oms::ssp::Draft20180219::ssd::enumerations);

for (pugi::xml_node enumItems = enumeration.child(oms::ssp::Version1_0::ssc::enumeration_type); enumItems; enumItems = enumItems.next_sibling(oms::ssp::Version1_0::ssc::enumeration_type))
{
// entry found
if (enumItems.attribute("name").as_string() == enumTypename)
{
std::map<std::string, std::string> enumerationItems;
for (pugi::xml_node enumItem = enumItems.child(oms::ssp::Version1_0::ssc::enum_item); enumItem; enumItem = enumItem.next_sibling(oms::ssp::Version1_0::ssc::enum_item))
{
enumerationItems[enumItem.attribute("name").as_string()] = enumItem.attribute("value").as_string();
}
modeldescriptionTypeDefinitions[enumTypename] = enumerationItems;
}
}
}

oms_status_enu_t oms::Values::parseModelDescription(const filesystem::path& root, std::string& guid_)
{

Expand Down Expand Up @@ -1513,6 +1559,21 @@ oms_status_enu_t oms::Values::parseModelDescription(const filesystem::path& root
for(pugi::xml_node_iterator it = node.begin(); it != node.end(); ++it)
{
std::string name = it->name();
if (name == "TypeDefinitions")
{
pugi::xml_node simpleType = it->child("SimpleType");
pugi::xml_node Enumeration = simpleType.child("Enumeration");
if (Enumeration)
{
std::map<std::string, std::string> enumerationItems;
for (pugi::xml_node enumItem = Enumeration.child("Item"); enumItem; enumItem = enumItem.next_sibling("Item"))
{
// std::cout << "\n loop: " << enumItem.attribute("name").as_string() << "==>" << enumItem.attribute("value").as_string();
enumerationItems[enumItem.attribute("name").as_string()] = enumItem.attribute("value").as_string();
}
modeldescriptionTypeDefinitions[simpleType.attribute("name").as_string()] = enumerationItems;
}
}
if (name == "UnitDefinitions")
{
//std::cout << "\nParse Unit Definitions";
Expand Down Expand Up @@ -1563,6 +1624,10 @@ oms_status_enu_t oms::Values::parseModelDescription(const filesystem::path& root
{
modelDescriptionBooleanStartValues[scalarVariable.attribute("name").as_string()] = scalarVariable.child("Boolean").attribute("start").as_bool();
}
if (strlen(scalarVariable.child("Enumeration").attribute("declaredType").as_string()) != 0)
{
modeldescriptionEnumeration[scalarVariable.attribute("name").as_string()] = scalarVariable.child("Enumeration").attribute("declaredType").as_string();
}
}
}
if (name == "ModelStructure")
Expand Down
7 changes: 6 additions & 1 deletion src/OMSimulatorLib/Values.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ namespace oms
oms_status_enu_t setUnit(const ComRef& cref, const std::string& value);
void setUnitDefinitions(const ComRef& cref);
void getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& unitDefinitions);
void getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions);
void updateModelDescriptionRealStartValue(const ComRef& cref, double value);
void updateModelDescriptionIntegerStartValue(const ComRef& cref, int value);
void updateModelDescriptionBooleanStartValue(const ComRef& cref, bool value);
Expand Down Expand Up @@ -86,7 +87,7 @@ namespace oms

std::string getUnit(ComRef& cref) const;
std::string getUnitFromModeldescription(ComRef& cref) const;

std::string getEnumerationTypeFromModeldescription(ComRef& cref) const;
oms_status_enu_t exportToSSD(pugi::xml_node& node) const;
oms_status_enu_t importFromSnapshot(const pugi::xml_node& node, const std::string& sspVersion, const Snapshot& snapshot, std::string variantName);
oms_status_enu_t importFromSnapshot(const Snapshot& snapshot, const std::string& ssvFilePath, const std::string& ssmFilename);
Expand All @@ -102,6 +103,7 @@ namespace oms
oms_status_enu_t exportUnitDefinitions(Snapshot &snapshot, std::string filename, std::string variantName) const;
oms_status_enu_t exportUnitDefinitionsToSSVTemplate(Snapshot &snapshot, std::string filename);
void importUnitDefinitions(const pugi::xml_node& node);
void importEnumerationDefinitions(const pugi::xml_node& node, std::string& enumTypeName);

void exportToSSVTemplate(pugi::xml_node& ssvNode, const ComRef& cref); ///< start values read from modelDescription.xml and creates a ssv template
void exportReduceSSV(pugi::xml_node& ssvNode, const ComRef& cref); ///< reduced SSV file which contains only the referenced crefs in parametermapping
Expand Down Expand Up @@ -167,6 +169,9 @@ namespace oms

std::map<std::string, std::map<std::string, std::string>> modeldescriptionUnitDefinitions; ///< <UnitDefinitions> list read from modeldescription.xml

std::map<std::string, std::map<std::string, std::string>> modeldescriptionTypeDefinitions; ///< <TypeDefinitions> list read from modeldescription.xml
std::map<std::string, std::string> modeldescriptionEnumeration; ///< enumeration declared type list list read from modeldescription.xml

std::multimap<ComRef, ComRef> mappedEntry; ///< parameter names and values provided in the parameter source are to be mapped to the parameters of the component or system

std::vector<Values> parameterResources; ///< list of parameter resources provided inline or .ssv files
Expand Down
5 changes: 4 additions & 1 deletion src/OMSimulatorLib/XercesValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,12 @@ oms_status_enu_t oms::XercesValidator::validateSSP(const char *ssd, const std::s
return logError("executable path could not be found");

filesystem::path schemaRootPath (path);
filesystem::path schemaSSDPath, schemaSSVPath, schemaSSMPath;
filesystem::path schemaSSDPath, schemaSSVPath, schemaSSMPath, schemaSSCPath;

schemaSSDPath = schemaRootPath / "../share/OMSimulator/schema/ssp/SystemStructureDescription.xsd";
schemaSSVPath = schemaRootPath / "../share/OMSimulator/schema/ssp/SystemStructureParameterValues.xsd";
schemaSSMPath = schemaRootPath / "../share/OMSimulator/schema/ssp/SystemStructureParameterMapping.xsd";
schemaSSCPath = schemaRootPath / "../share/OMSimulator/schema/ssp/SystemStructureCommon.xsd";

// std::cout << "schemaPath: " << schemaFilePath.generic_string() << "\n" << filesystem::absolute(schemaFilePath).generic_string() << "\n";

Expand All @@ -165,6 +166,7 @@ oms_status_enu_t oms::XercesValidator::validateSSP(const char *ssd, const std::s
schemaSSDPath = schemaRootPath / "../../share/OMSimulator/schema/ssp/SystemStructureDescription.xsd";
schemaSSVPath = schemaRootPath / "../../share/OMSimulator/schema/ssp/SystemStructureParameterValues.xsd";
schemaSSMPath = schemaRootPath / "../../share/OMSimulator/schema/ssp/SystemStructureParameterMapping.xsd";
schemaSSCPath = schemaRootPath / "../../share/OMSimulator/schema/ssp/SystemStructureCommon.xsd";
}

XercesDOMParser domParser;
Expand Down Expand Up @@ -195,6 +197,7 @@ oms_status_enu_t oms::XercesValidator::validateSSP(const char *ssd, const std::s
std::string ssdTargetNameSpacePath = "http://ssp-standard.org/SSP1/SystemStructureDescription " + schemaSSDPath.generic_string();
ssdTargetNameSpacePath = ssdTargetNameSpacePath + " http://ssp-standard.org/SSP1/SystemStructureParameterValues " + schemaSSVPath.generic_string();
ssdTargetNameSpacePath = ssdTargetNameSpacePath + " http://ssp-standard.org/SSP1/SystemStructureParameterMapping " + schemaSSMPath.generic_string();
ssdTargetNameSpacePath = ssdTargetNameSpacePath + " http://ssp-standard.org/SSP1/SystemStructureCommon " + schemaSSCPath.generic_string();

domParser.setExternalSchemaLocation(ssdTargetNameSpacePath.c_str());

Expand Down
Loading