Repository: NREL/OpenStudio (language: python)

Issue:
Modify Model::load(path&) to use VersionTranslator by default
Enhancement Request
--------------

It's been like this for ever, but it's weird that Model::load just assumes this is at the right version.  It's very confusing to new users too, and they struggle with knowing how to load a model.

https://github.com/NREL/OpenStudio/blob/92da27b27de50e076ce3bdc5032e4f348e2231e8/src/model/Model.cpp#L1836-L1858

 It shouldn't be that verbose to load a model

https://github.com/NREL/OpenStudio-workflow-gem/blob/cf99e6096f33b717df79a71c245a4d7aa4ccb7a6/lib/openstudio/workflow/util/model.rb#L51-L70

## Detailed Description

At the very least we should provide an override or extra bool parameter.

## Possible Implementation

Straightforward

Modify Model::load(path&) to use VersionTranslator by default
Enhancement Request
--------------

It's been like this for ever, but it's weird that Model::load just assumes this is at the right version.  It's very confusing to new users too, and they struggle with knowing how to load a model.

https://github.com/NREL/OpenStudio/blob/92da27b27de50e076ce3bdc5032e4f348e2231e8/src/model/Model.cpp#L1836-L1858

 It shouldn't be that verbose to load a model

https://github.com/NREL/OpenStudio-workflow-gem/blob/cf99e6096f33b717df79a71c245a4d7aa4ccb7a6/lib/openstudio/workflow/util/model.rb#L51-L70

## Detailed Description

At the very least we should provide an override or extra bool parameter.

## Possible Implementation

Straightforward

Modify Model::load(path&) to use VersionTranslator by default
Enhancement Request
--------------

It's been like this for ever, but it's weird that Model::load just assumes this is at the right version.  It's very confusing to new users too, and they struggle with knowing how to load a model.

https://github.com/NREL/OpenStudio/blob/92da27b27de50e076ce3bdc5032e4f348e2231e8/src/model/Model.cpp#L1836-L1858

 It shouldn't be that verbose to load a model

https://github.com/NREL/OpenStudio-workflow-gem/blob/cf99e6096f33b717df79a71c245a4d7aa4ccb7a6/lib/openstudio/workflow/util/model.rb#L51-L70

## Detailed Description

At the very least we should provide an override or extra bool parameter.

## Possible Implementation

Straightforward



Discussion / hints:
Two thumbs up for this. So annoying to version translate first. Love this issue. 
Here is how model is loaded in measure tests
https://github.com/NREL/openstudio-common-measures-gem/blob/develop/lib/measures/ChangeBuildingLocation/tests/change_building_location_test.rb#L39-43

Two thumbs up for this. So annoying to version translate first. Love this issue. 
Here is how model is loaded in measure tests
https://github.com/NREL/openstudio-common-measures-gem/blob/develop/lib/measures/ChangeBuildingLocation/tests/change_building_location_test.rb#L39-43

Two thumbs up for this. So annoying to version translate first. Love this issue. 
Here is how model is loaded in measure tests
https://github.com/NREL/openstudio-common-measures-gem/blob/develop/lib/measures/ChangeBuildingLocation/tests/change_building_location_test.rb#L39-43


Fix patch:
diff --git a/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_7_0_TDB.md b/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_7_0_TDB.md
index 3b1265716db..0d145e891d7 100644
--- a/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_7_0_TDB.md
+++ b/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_7_0_TDB.md
@@ -81,6 +81,7 @@ You can also refer to the [OpenStudio SDK Python Binding Version Compatibility M
 * [#4932](https://github.com/NREL/OpenStudio/pull/4932) - Support undisturbed ground temperature models on GroundHeatExchangerVertical
     * Fix #4930 - Support undisturbed ground temperature models on GroundHeatExchangerVertical
     * Update `GroundHeatExchanger:Vertical` to actually use the Ground Temeprature Model field
+* [#4923](https://github.com/NREL/OpenStudio/pull/4923) - Fix #4692 - Modify `Model::load` to use the VersionTranslator instead of loading it assuming the version of the loaded OSM is the same as the current SDK version being used.
 
 ## Minor changes and bug fixes
 
diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt
index 9c47de51d50..d97a7620cde 100644
--- a/resources/CMakeLists.txt
+++ b/resources/CMakeLists.txt
@@ -175,6 +175,8 @@ set(model_resources_src
   model/ASHRAECourthouse.osm
   model/A205ExampleChiller.RS0001.a205.cbor
   model/4837_SpaceVolume.osm
+  model/empty361.osm
+  model/empty361/workflow.osw
 )
 
 
diff --git a/resources/model/empty361.osm b/resources/model/empty361.osm
new file mode 100644
index 00000000000..9e538acfe7f
--- /dev/null
+++ b/resources/model/empty361.osm
@@ -0,0 +1,5 @@
+
+OS:Version,
+  {e2190a61-e3f3-4d4b-8c0b-7a9c2342180e}, !- Handle
+  3.6.1;                                  !- Version Identifier
+
diff --git a/resources/model/empty361/workflow.osw b/resources/model/empty361/workflow.osw
new file mode 100644
index 00000000000..147ae7382be
--- /dev/null
+++ b/resources/model/empty361/workflow.osw
@@ -0,0 +1,6 @@
+{
+   "created_at" : "20230704T152451Z",
+   "seed_file" : "../empty361.osm",
+   "steps" : [],
+   "updated_at" : "20230704T152548Z"
+}
\ No newline at end of file
diff --git a/src/model/Model.cpp b/src/model/Model.cpp
index 06dbe153e22..18caded3bf1 100644
--- a/src/model/Model.cpp
+++ b/src/model/Model.cpp
@@ -21,8 +21,11 @@
 #include <utilities/idd/IddEnums.hxx>
 #include <utilities/idd/OS_Version_FieldEnums.hxx>
 
+#include "../osversion/VersionTranslator.hpp"
+
 #include "../utilities/core/Assert.hpp"
 #include "../utilities/core/ContainersMove.hpp"
+#include "../utilities/core/Filesystem.hpp"
 #include "../utilities/core/PathHelpers.hpp"
 
 #include "../utilities/idd/IddEnums.hpp"
@@ -1840,27 +1843,26 @@ namespace model {
   }
 
   boost::optional<Model> Model::load(const path& osmPath) {
-    OptionalModel result;
-    OptionalIdfFile oIdfFile = IdfFile::load(osmPath, IddFileType::OpenStudio);
-    if (oIdfFile) {
-      try {
-        result = Model(*oIdfFile);
-      } catch (...) {
-      }
-    }
 
-    if (result) {
-      // Load the workflow.osw in the model's companion folder
-      path workflowJSONPath = getCompanionFolder(osmPath) / toPath("workflow.osw");
-      if (exists(workflowJSONPath)) {
-        boost::optional<WorkflowJSON> workflowJSON = WorkflowJSON::load(workflowJSONPath);
-        if (workflowJSON) {
-          result->setWorkflowJSON(*workflowJSON);
-        }
+    if (!openstudio::filesystem::is_regular_file(osmPath)) {
+      LOG(Warn, "Path is not a valid file: " << osmPath);
+      return boost::none;
+    }
+    openstudio::osversion::VersionTranslator vt;
+    boost::optional<openstudio::model::Model> model_ = vt.loadModel(osmPath);
+    if (!model_) {
+      LOG(Warn, "Failed to load model at " << osmPath);
+      return boost::none;
+    }
+    // Load the workflow.osw in the model's companion folder
+    const openstudio::path workflowJSONPath = getCompanionFolder(osmPath) / toPath("workflow.osw");
+    if (exists(workflowJSONPath)) {
+      if (boost::optional<WorkflowJSON> workflowJSON_ = WorkflowJSON::load(workflowJSONPath)) {
+        model_->setWorkflowJSON(*workflowJSON_);
       }
     }
 
-    return result;
+    return model_;
   }
 
   boost::optional<Model> Model::load(const path& osmPath, const path& workflowJSONPath) {


Test patch:
diff --git a/src/model/test/Model_GTest.cpp b/src/model/test/Model_GTest.cpp
index 8ad9498582f..b000740e612 100644
--- a/src/model/test/Model_GTest.cpp
+++ b/src/model/test/Model_GTest.cpp
@@ -129,16 +129,18 @@
 #include "../ExternalInterface.hpp"
 #include "../ExternalInterface_Impl.hpp"
 
-#include "../../utilities/sql/SqlFile.hpp"
+#include "../../utilities/core/PathHelpers.hpp"
 #include "../../utilities/data/TimeSeries.hpp"
 #include "../../utilities/idf/IdfFile.hpp"
 #include "../../utilities/idf/Workspace.hpp"
 #include "../../utilities/idf/WorkspaceObject.hpp"
 #include "../../utilities/idf/ValidityReport.hpp"
+#include "../../utilities/sql/SqlFile.hpp"
 
 #include "../../osversion/VersionTranslator.hpp"
 
 #include <utilities/idd/IddEnums.hxx>
+#include <OpenStudio.hxx>
 
 #include <boost/algorithm/string/case_conv.hpp>
 
@@ -1160,3 +1162,28 @@ TEST_F(ModelFixture, UniqueModelObjectCachedGetters) {
   EXPECT_TRUE(m.getOptionalUniqueModelObject<ExternalInterface>());
   EXPECT_EQ(++i, m.getModelObjects<ModelObject>().size());
 }
+
+TEST_F(ModelFixture, Model_load) {
+
+  openstudio::path modelPath = resourcesPath() / "model" / toPath("empty361.osm");
+  ASSERT_TRUE(openstudio::filesystem::exists(modelPath));
+
+  const openstudio::path workflowJSONPath = getCompanionFolder(modelPath) / toPath("workflow.osw");
+  ASSERT_TRUE(openstudio::filesystem::exists(workflowJSONPath));
+
+  // Check that the versionObject is indeed translated to the current version
+  boost::optional<Model> model_ = Model::load(modelPath);
+  ASSERT_TRUE(model_);
+  auto versionObject_ = model_->versionObject();
+  ASSERT_TRUE(versionObject_);
+  EXPECT_EQ(openStudioVersion(), versionObject_->getString(1).get());
+
+  // Check that the workflowJSON in the companion folder is correctly loaded
+  auto workflowJSON = model_->workflowJSON();
+  auto p_ = workflowJSON.oswPath();
+  ASSERT_TRUE(p_);
+  EXPECT_EQ(workflowJSONPath, *p_);
+
+  ASSERT_TRUE(workflowJSON.seedFile());
+  EXPECT_EQ(workflowJSON.seedFile().get(), openstudio::toPath("../empty361.osm"));
+}