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

Schedule:File relative paths #4879

Merged
merged 40 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6a4767b
Add new ft test for schedule file relative path.
joseph-robertson May 9, 2023
e13f101
Try filePath as relative path for FT switch.
joseph-robertson May 9, 2023
1b8cfff
Formatting.
joseph-robertson May 9, 2023
c4b78b8
Updates to new test.
joseph-robertson May 9, 2023
2637831
Missing include and minor cleanup.
joseph-robertson May 9, 2023
9fee86f
Add more ft tests for different schedule file ctors.
joseph-robertson May 9, 2023
d60f631
Missing includes.
joseph-robertson May 9, 2023
91b7f64
Use the correct external file ctor.
joseph-robertson May 9, 2023
014991a
Fix tests.
joseph-robertson May 9, 2023
76c8024
Only error check on path existence if copyFile is true or path is abs…
joseph-robertson May 9, 2023
cc84c90
Add new ft test for schedule file relative path.
joseph-robertson May 9, 2023
fbcf19b
Try filePath as relative path for FT switch.
joseph-robertson May 9, 2023
40a5e3a
Formatting.
joseph-robertson May 9, 2023
838edd0
Updates to new test.
joseph-robertson May 9, 2023
f0c7b5b
Missing include and minor cleanup.
joseph-robertson May 9, 2023
67a9567
Add more ft tests for different schedule file ctors.
joseph-robertson May 9, 2023
d429cf9
Missing includes.
joseph-robertson May 9, 2023
500574f
Use the correct external file ctor.
joseph-robertson May 9, 2023
e935dae
Fix tests.
joseph-robertson May 9, 2023
bdddd1f
Only error check on path existence if copyFile is true or path is abs…
joseph-robertson May 9, 2023
528ac24
Merge branch 'schedule-file-rel-path' of github.com:NREL/OpenStudio i…
joseph-robertson Oct 26, 2023
3001627
Merge branch 'develop' into schedule-file-rel-path
joseph-robertson Oct 26, 2023
4cc1a59
Updates for externalfile and new ft tests.
joseph-robertson Oct 26, 2023
2a30424
Update externalfile idd to have bool translatefilename field.
joseph-robertson Oct 26, 2023
9c0c625
Update ft to use translatefilename.
joseph-robertson Oct 26, 2023
4e3bc6c
Update externalfile files for new field.
joseph-robertson Oct 26, 2023
e3aa21d
Update schedulefile ctor for new field.
joseph-robertson Oct 26, 2023
48c7986
Get the field name correct.
joseph-robertson Oct 26, 2023
4c5591c
Typo.
joseph-robertson Oct 27, 2023
045abc0
Move translatefilename over to schedulefile instead.
joseph-robertson Oct 27, 2023
c4d2572
Update schedulefile ctor.
joseph-robertson Oct 27, 2023
6451066
Add methods for defaulted and reset.
joseph-robertson Oct 27, 2023
0116c68
Updates to model and ft tests.
joseph-robertson Oct 27, 2023
247cdef
Add choice to idd.
joseph-robertson Oct 27, 2023
7345dea
Update new ft tests.
joseph-robertson Oct 27, 2023
30e34f1
Merge branch 'develop' into schedule-file-rel-path
jmarrec Oct 31, 2023
d64e7fb
Rename IDD Field, move path logic into model `openstudio::path Schedu…
jmarrec Oct 31, 2023
fb604f5
Make tests platform and current directory agnostics
jmarrec Oct 31, 2023
c008154
Merge pull request #5010 from NREL/schedule-file-rel-path-2
jmarrec Oct 31, 2023
28a3f30
Merge branch 'develop' into schedule-file-rel-path
DavidGoldwasser Nov 2, 2023
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
9 changes: 8 additions & 1 deletion resources/model/OpenStudio.idd
Original file line number Diff line number Diff line change
Expand Up @@ -5104,13 +5104,20 @@ OS:Schedule:File,
\key 20
\key 30
\key 60
A7 ; \field Adjust Schedule for Daylight Savings
A7, \field Adjust Schedule for Daylight Savings
\note "No" means do not include Daylight Savings Time in the schedule, instead, use the schedule directly from the Schedule:File csv (default)
\note "Yes" means include Daylight Savings Time to the schedule
\type choice
\key Yes
\key No
\default Yes
A8; \field Translate File With Relative Path
\note "No" means the absolute path of the ExternalFile is resolved and translated to IDF.
\note "Yes" means only the filename (relative) is translated
\type choice
\default No
\key Yes
\key No

\group OpenStudio Geometry

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,8 @@ namespace energyplus {
idfObject.setString(openstudio::Schedule_FileFields::ScheduleTypeLimitsName, idfScheduleTypeLimits->name().get());
}
}

path filePath = modelObject.externalFile().filePath();
if (!exists(filePath)) {
LOG(Warn, "Cannot find file \"" << filePath << "\"");
} else {
// make the path correct for this system
filePath = system_complete(filePath);
}

// DLM: this path is going to be in the temp dir, might want to fix it up when saving model temp dir
idfObject.setString(openstudio::Schedule_FileFields::FileName, toString(filePath));
idfObject.setString(openstudio::Schedule_FileFields::FileName, toString(modelObject.translatedFilePath()));

idfObject.setInt(openstudio::Schedule_FileFields::ColumnNumber, modelObject.columnNumber());
idfObject.setInt(openstudio::Schedule_FileFields::RowstoSkipatTop, modelObject.rowstoSkipatTop());
Expand Down
141 changes: 141 additions & 0 deletions src/energyplus/Test/ScheduleInterval_GTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@
#include "../../model/ScheduleFixedInterval_Impl.hpp"
#include "../../model/ScheduleVariableInterval.hpp"
#include "../../model/ScheduleVariableInterval_Impl.hpp"
#include "../../model/ExternalFile.hpp"
#include "../../model/ExternalFile_Impl.hpp"
#include "../../model/ScheduleFile.hpp"
#include "../../model/ScheduleFile_Impl.hpp"
#include "../../model/YearDescription.hpp"
#include "../../model/YearDescription_Impl.hpp"

#include <utilities/idd/IddEnums.hxx>

#include "../../utilities/core/PathHelpers.hpp"
#include "../../utilities/core/Filesystem.hpp"
#include <resources.hxx>

#include <boost/regex.hpp>

#include <sstream>
Expand Down Expand Up @@ -1850,3 +1856,138 @@ TEST_F(EnergyPlusFixture, DISABLED_ForwardTranslator_ScheduleVariableInterval_Da
// check that there were XX untils
//EXPECT_EQ(864, numUntils);
}

TEST_F(EnergyPlusFixture, ScheduleFileRelativePath) {

openstudio::path absoluteScheduleFilePath = resourcesPath() / toPath("model/schedulefile.csv");
ASSERT_TRUE(openstudio::filesystem::is_regular_file(absoluteScheduleFilePath));
ASSERT_TRUE(absoluteScheduleFilePath.is_absolute());

openstudio::path curDirPath = boost::filesystem::current_path();
openstudio::path relativeScheduleFilePath = openstudio::filesystem::relative(absoluteScheduleFilePath, curDirPath);
ASSERT_TRUE(relativeScheduleFilePath.is_relative());

// ScheduleFile(external_file(/abs/path))
{
Model model;
EXPECT_EQ(0u, model.getConcreteModelObjects<ExternalFile>().size());
EXPECT_EQ(0u, model.getConcreteModelObjects<ScheduleFile>().size());

boost::optional<ExternalFile> external_file = ExternalFile::getExternalFile(model, openstudio::toString(absoluteScheduleFilePath));
ASSERT_TRUE(external_file);
ScheduleFile schedule(*external_file);
EXPECT_TRUE(schedule.setTranslateFileWithRelativePath(true));
EXPECT_TRUE(schedule.translateFileWithRelativePath());
EXPECT_EQ(1u, model.getConcreteModelObjects<ScheduleFile>().size());
EXPECT_EQ(1u, model.getConcreteModelObjects<ExternalFile>().size());
ExternalFile externalfile = schedule.externalFile();
EXPECT_EQ(1u, externalfile.scheduleFiles().size());
EXPECT_EQ(openstudio::toString(absoluteScheduleFilePath.filename()), externalfile.fileName());
EXPECT_TRUE(toPath(externalfile.fileName()).is_relative());
EXPECT_FALSE(externalfile.filePath().is_relative());
EXPECT_NE(toPath(externalfile.fileName()), externalfile.filePath());

ForwardTranslator ft;
Workspace workspace = ft.translateModel(model);

std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::Schedule_File);
ASSERT_EQ(1u, objects.size());

boost::optional<std::string> fileName = objects[0].getString(2); // File Name
ASSERT_TRUE(fileName);
EXPECT_TRUE(toPath(fileName.get()).is_relative()); // rel path
EXPECT_NE(externalfile.filePath(), fileName.get());
}

// ScheduleFile(external_file(/rel/path))
{
Model model;
EXPECT_EQ(0u, model.getConcreteModelObjects<ExternalFile>().size());
EXPECT_EQ(0u, model.getConcreteModelObjects<ScheduleFile>().size());

boost::optional<ExternalFile> external_file = ExternalFile::getExternalFile(model, openstudio::toString(relativeScheduleFilePath));
ASSERT_TRUE(external_file);
ScheduleFile schedule(*external_file);
EXPECT_TRUE(schedule.setTranslateFileWithRelativePath(true));
EXPECT_TRUE(schedule.translateFileWithRelativePath());
EXPECT_EQ(1u, model.getConcreteModelObjects<ScheduleFile>().size());
EXPECT_EQ(1u, model.getConcreteModelObjects<ExternalFile>().size());
ExternalFile externalfile = schedule.externalFile();
EXPECT_EQ(1u, externalfile.scheduleFiles().size());
EXPECT_EQ(openstudio::toString(relativeScheduleFilePath.filename()), externalfile.fileName());
EXPECT_TRUE(toPath(externalfile.fileName()).is_relative());
EXPECT_FALSE(externalfile.filePath().is_relative());
EXPECT_NE(toPath(externalfile.fileName()), externalfile.filePath());

ForwardTranslator ft;
Workspace workspace = ft.translateModel(model);

std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::Schedule_File);
ASSERT_EQ(1u, objects.size());

boost::optional<std::string> fileName = objects[0].getString(2); // File Name
ASSERT_TRUE(fileName);
EXPECT_TRUE(toPath(fileName.get()).is_relative()); // rel path
EXPECT_NE(externalfile.filePath(), fileName.get());
}

// ScheduleFile(model, /abs/path)
{
Model model;
EXPECT_EQ(0u, model.getConcreteModelObjects<ExternalFile>().size());
EXPECT_EQ(0u, model.getConcreteModelObjects<ScheduleFile>().size());

ScheduleFile schedule(model, openstudio::toString(absoluteScheduleFilePath));
EXPECT_TRUE(schedule.setTranslateFileWithRelativePath(true));
EXPECT_TRUE(schedule.translateFileWithRelativePath());
EXPECT_EQ(1u, model.getConcreteModelObjects<ScheduleFile>().size());
EXPECT_EQ(1u, model.getConcreteModelObjects<ExternalFile>().size());
ExternalFile externalfile = schedule.externalFile();
EXPECT_EQ(1u, externalfile.scheduleFiles().size());
EXPECT_EQ(openstudio::toString(absoluteScheduleFilePath), externalfile.fileName());
EXPECT_FALSE(toPath(externalfile.fileName()).is_relative());
EXPECT_FALSE(externalfile.filePath().is_relative());
EXPECT_EQ(toPath(externalfile.fileName()), externalfile.filePath());

ForwardTranslator ft;
Workspace workspace = ft.translateModel(model);

std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::Schedule_File);
ASSERT_EQ(1u, objects.size());

boost::optional<std::string> fileName = objects[0].getString(2); // File Name
ASSERT_TRUE(fileName);
EXPECT_FALSE(toPath(fileName.get()).is_relative()); // abs path
EXPECT_EQ(externalfile.filePath(), fileName.get());
}

// ScheduleFile(model, /rel/path)
{
Model model;
EXPECT_EQ(0u, model.getConcreteModelObjects<ExternalFile>().size());
EXPECT_EQ(0u, model.getConcreteModelObjects<ScheduleFile>().size());

ScheduleFile schedule(model, openstudio::toString(relativeScheduleFilePath));
EXPECT_TRUE(schedule.setTranslateFileWithRelativePath(true));
EXPECT_TRUE(schedule.translateFileWithRelativePath());
EXPECT_EQ(1u, model.getConcreteModelObjects<ScheduleFile>().size());
EXPECT_EQ(1u, model.getConcreteModelObjects<ExternalFile>().size());
ExternalFile externalfile = schedule.externalFile();
EXPECT_EQ(1u, externalfile.scheduleFiles().size());
EXPECT_EQ(openstudio::toString(relativeScheduleFilePath), externalfile.fileName());
EXPECT_TRUE(toPath(externalfile.fileName()).is_relative());
EXPECT_TRUE(externalfile.filePath().is_relative()) << externalfile.filePath();
EXPECT_EQ(toPath(externalfile.fileName()), externalfile.filePath());

ForwardTranslator ft;
Workspace workspace = ft.translateModel(model);

std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::Schedule_File);
ASSERT_EQ(1u, objects.size());

boost::optional<std::string> fileName = objects[0].getString(2); // File Name
ASSERT_TRUE(fileName);
EXPECT_TRUE(toPath(fileName.get()).is_relative()); // rel path
EXPECT_EQ(externalfile.filePath(), fileName.get());
}
}
60 changes: 60 additions & 0 deletions src/model/ScheduleFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,16 @@ namespace model {
return csvFile;
}

bool ScheduleFile_Impl::translateFileWithRelativePath() const {
boost::optional<std::string> value = getString(OS_Schedule_FileFields::TranslateFileWithRelativePath, true);
OS_ASSERT(value);
return openstudio::istringEqual(value.get(), "Yes");
}

bool ScheduleFile_Impl::isTranslateFileWithRelativePathDefaulted() const {
return isEmpty(OS_Schedule_FileFields::TranslateFileWithRelativePath);
}

/* FIXME!
openstudio::TimeSeries ScheduleFile_Impl::timeSeries(unsigned columnIndex) const
{
Expand Down Expand Up @@ -376,6 +386,36 @@ namespace model {
}*/
}

bool ScheduleFile_Impl::setTranslateFileWithRelativePath(bool translateFileWithRelativePath) {
bool result = false;
if (translateFileWithRelativePath) {
result = setString(OS_Schedule_FileFields::TranslateFileWithRelativePath, "Yes");
} else {
result = setString(OS_Schedule_FileFields::TranslateFileWithRelativePath, "No");
}
OS_ASSERT(result);
return result;
}

void ScheduleFile_Impl::resetTranslateFileWithRelativePath() {
const bool result = setString(OS_Schedule_FileFields::TranslateFileWithRelativePath, "");
OS_ASSERT(result);
}

openstudio::path ScheduleFile_Impl::translatedFilePath() const {
if (translateFileWithRelativePath()) {
return toPath(externalFile().fileName());
}
openstudio::path filePath = externalFile().filePath();
if (!exists(filePath)) {
LOG(Warn, "Cannot find file \"" << filePath << "\"");
} else {
// make the path correct for this system
filePath = system_complete(filePath);
}
return filePath;
}

} // namespace detail

ScheduleFile::ScheduleFile(const ExternalFile& externalfile, int column, int rowsToSkip)
Expand Down Expand Up @@ -477,6 +517,14 @@ namespace model {
return getImpl<detail::ScheduleFile_Impl>()->csvFile();
}

bool ScheduleFile::translateFileWithRelativePath() const {
return getImpl<detail::ScheduleFile_Impl>()->translateFileWithRelativePath();
}

bool ScheduleFile::isTranslateFileWithRelativePathDefaulted() const {
return getImpl<detail::ScheduleFile_Impl>()->isTranslateFileWithRelativePathDefaulted();
}

/* FIXME!
openstudio::TimeSeries ScheduleFile::timeSeries(unsigned columnIndex) const {
return getImpl<detail::ScheduleFile_Impl>()->timeSeries(columnIndex);
Expand Down Expand Up @@ -551,6 +599,18 @@ unsigned ScheduleFile::addTimeSeries(const openstudio::TimeSeries& timeSeries) {
getImpl<detail::ScheduleFile_Impl>()->resetAdjustScheduleforDaylightSavings();
}

bool ScheduleFile::setTranslateFileWithRelativePath(bool translateFileWithRelativePath) {
return getImpl<detail::ScheduleFile_Impl>()->setTranslateFileWithRelativePath(translateFileWithRelativePath);
}

void ScheduleFile::resetTranslateFileWithRelativePath() {
getImpl<detail::ScheduleFile_Impl>()->resetTranslateFileWithRelativePath();
}

openstudio::path ScheduleFile::translatedFilePath() const {
return getImpl<detail::ScheduleFile_Impl>()->translatedFilePath();
}

/// @cond
ScheduleFile::ScheduleFile(std::shared_ptr<detail::ScheduleFile_Impl> impl) : ScheduleInterval(std::move(impl)) {}
/// @endcond
Expand Down
11 changes: 11 additions & 0 deletions src/model/ScheduleFile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ namespace model {

boost::optional<CSVFile> csvFile() const;

bool translateFileWithRelativePath() const;

bool isTranslateFileWithRelativePathDefaulted() const;

//@}
/** @name Setters */
//@{
Expand Down Expand Up @@ -120,10 +124,17 @@ namespace model {

/* FIXME! unsigned addTimeSeries(const openstudio::TimeSeries& timeSeries); */

bool setTranslateFileWithRelativePath(bool translateFileWithRelativePath);

void resetTranslateFileWithRelativePath();

//@}
/** @name Other */
//@{

// Depending on the value of 'Translate File With Relative Path', returns an absolute or a relative path
openstudio::path translatedFilePath() const;

//@}
protected:
/// @cond
Expand Down
10 changes: 10 additions & 0 deletions src/model/ScheduleFile_Impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ namespace model {

boost::optional<CSVFile> csvFile() const;

bool translateFileWithRelativePath() const;

bool isTranslateFileWithRelativePathDefaulted() const;

//@}
/** @name Setters */
//@{
Expand Down Expand Up @@ -121,10 +125,16 @@ namespace model {
// ensure that this object does not contain the date 2/29
virtual void ensureNoLeapDays() override;

bool setTranslateFileWithRelativePath(bool translateFileWithRelativePath);

void resetTranslateFileWithRelativePath();

//@}
/** @name Other */
//@{

openstudio::path translatedFilePath() const;

//@}
protected:
private:
Expand Down
13 changes: 13 additions & 0 deletions src/model/test/ScheduleInterval_GTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,19 @@ TEST_F(ModelFixture, ScheduleFile) {
schedule3.resetAdjustScheduleforDaylightSavings();
EXPECT_TRUE(schedule3.isAdjustScheduleforDaylightSavingsDefaulted());

EXPECT_FALSE(schedule3.translateFileWithRelativePath());
EXPECT_TRUE(schedule3.isTranslateFileWithRelativePathDefaulted());
EXPECT_EQ(externalfile->filePath(), schedule3.translatedFilePath());

EXPECT_TRUE(schedule3.setTranslateFileWithRelativePath(true));
EXPECT_TRUE(schedule3.translateFileWithRelativePath());
EXPECT_FALSE(schedule3.isTranslateFileWithRelativePathDefaulted());
EXPECT_EQ(toPath(externalfile->fileName()), schedule3.translatedFilePath());

schedule3.resetTranslateFileWithRelativePath();
EXPECT_FALSE(schedule3.translateFileWithRelativePath());
EXPECT_TRUE(schedule3.isTranslateFileWithRelativePathDefaulted());

// shouldn't create a new object
boost::optional<ExternalFile> externalfile2 = ExternalFile::getExternalFile(model, openstudio::toString(p));
ASSERT_TRUE(externalfile2);
Expand Down