TEST_F(ProjectFixture, RubyMeasureRecord_RubyScript) { // Measures MeasureVector measures; // Null Measure measures.push_back(NullMeasure()); openstudio::path rubyLibDirPath = openstudio::toPath(rubyLibDir()); openstudio::path perturbScript = rubyLibDirPath/openstudio::toPath("openstudio/runmanager/rubyscripts/PerturbObject.rb"); RubyMeasure rubyMeasure(perturbScript, FileReferenceType::OSM, FileReferenceType::OSM); rubyMeasure.addArgument("inputPath", "in.osm"); rubyMeasure.addArgument("outputPath", "out.osm"); rubyMeasure.addArgument("objectType", "OS:Material"); rubyMeasure.addArgument("nameRegex", "I02 50mm insulation board"); rubyMeasure.addArgument("field", "3"); rubyMeasure.addArgument("value", "0.10"); // RubyMeasure measures.push_back(rubyMeasure); // Variables VariableVector variables; variables.push_back(MeasureGroup("Wall Construction",measures)); // Workflow openstudio::runmanager::Workflow workflow; // Problem Problem problem("Variable",variables,workflow); // Save to database { ProjectDatabase database = getCleanDatabase("RubyMeasureRecord_RubyScript"); bool didStartTransaction = database.startTransaction(); EXPECT_TRUE(didStartTransaction); // Problem Record ProblemRecord problemRecord = ProblemRecord::factoryFromProblem(problem,database); database.save(); if (didStartTransaction) { EXPECT_TRUE(database.commitTransaction()); } // Variable Records InputVariableRecordVector measureGroupRecords = problemRecord.inputVariableRecords(); EXPECT_EQ(1u,measureGroupRecords.size()); // Discrete Variable Record MeasureGroupRecord measureGroupRecord = measureGroupRecords.at(0).cast<MeasureGroupRecord>(); EXPECT_EQ(2u,measureGroupRecord.measureRecordIds(true).size()); EXPECT_EQ(2u,measureGroupRecord.measureRecords(true).size()); RubyMeasureRecord rubyMeasureRecord(rubyMeasure,measureGroupRecord,0); EXPECT_EQ("MeasureRecords",rubyMeasureRecord.databaseTableName()); ObjectRecordVector objectRecordVector = rubyMeasureRecord.children(); EXPECT_EQ(6u,objectRecordVector.size()); // arguments objectRecordVector = rubyMeasureRecord.resources(); EXPECT_EQ(1u,objectRecordVector.size()); // script FileReferenceRecord scriptRecord = rubyMeasureRecord.fileReferenceRecord(); EXPECT_EQ("FileReferenceRecords",scriptRecord.databaseTableName()); Measure measure = rubyMeasureRecord.measure(); EXPECT_EQ(true,measure.isSelected()); ASSERT_TRUE(measure.optionalCast<RubyMeasure>()); RubyMeasure rubyMeasureCopy = measure.cast<RubyMeasure>(); EXPECT_FALSE(rubyMeasureCopy.usesBCLMeasure()); EXPECT_FALSE(rubyMeasureCopy.isUserScript()); EXPECT_EQ(6u,rubyMeasureCopy.arguments().size()); MeasureGroupRecord measureGroupRecordFromRuby = rubyMeasureRecord.measureGroupRecord().get(); EXPECT_EQ(measureGroupRecord.databaseTableName(),measureGroupRecordFromRuby.databaseTableName()); EXPECT_EQ(measureGroupRecord.id(),measureGroupRecordFromRuby.id()); } // Reopen database { ProjectDatabase database = getExistingDatabase("RubyMeasureRecord_RubyScript"); ProblemRecordVector problemRecords = ProblemRecord::getProblemRecords(database); ASSERT_FALSE(problemRecords.empty()); EXPECT_EQ(1u,problemRecords.size()); ProblemRecord problemRecord = problemRecords[0]; // COPY-PASTED FROM ABOVE // Variable Records InputVariableRecordVector measureGroupRecords = problemRecord.inputVariableRecords(); EXPECT_EQ(1u,measureGroupRecords.size()); // Discrete Variable Record MeasureGroupRecord measureGroupRecord = measureGroupRecords.at(0).cast<MeasureGroupRecord>(); EXPECT_EQ(2u,measureGroupRecord.measureRecordIds(true).size()); EXPECT_EQ(2u,measureGroupRecord.measureRecords(true).size()); RubyMeasureRecord rubyMeasureRecord(rubyMeasure,measureGroupRecord,0); EXPECT_EQ("MeasureRecords",rubyMeasureRecord.databaseTableName()); ObjectRecordVector objectRecordVector = rubyMeasureRecord.children(); EXPECT_EQ(6u,objectRecordVector.size()); // arguments objectRecordVector = rubyMeasureRecord.resources(); EXPECT_EQ(1u,objectRecordVector.size()); // script FileReferenceRecord scriptRecord = rubyMeasureRecord.fileReferenceRecord(); EXPECT_EQ("FileReferenceRecords",scriptRecord.databaseTableName()); Measure measure = rubyMeasureRecord.measure(); EXPECT_EQ(true,measure.isSelected()); ASSERT_TRUE(measure.optionalCast<RubyMeasure>()); RubyMeasure rubyMeasureCopy = measure.cast<RubyMeasure>(); EXPECT_FALSE(rubyMeasureCopy.usesBCLMeasure()); EXPECT_FALSE(rubyMeasureCopy.isUserScript()); EXPECT_EQ(6u,rubyMeasureCopy.arguments().size()); MeasureGroupRecord measureGroupRecordFromRuby = rubyMeasureRecord.measureGroupRecord().get(); EXPECT_EQ(measureGroupRecord.databaseTableName(),measureGroupRecordFromRuby.databaseTableName()); EXPECT_EQ(measureGroupRecord.id(),measureGroupRecordFromRuby.id()); } }
TEST_F(AnalysisFixture,DDACEAlgorithm_CompatibleProblemType) { // continuous problem with five variables VariableVector variables; BCLMeasure bclMeasure(resourcesPath() / toPath("utilities/BCL/Measures/v2/SetWindowToWallRatioByFacade")); RubyMeasure measure(bclMeasure); variables.push_back(RubyContinuousVariable("Var 1",OSArgument::makeDoubleArgument("wwr1"),measure)); variables.push_back(RubyContinuousVariable("Var 2",OSArgument::makeDoubleArgument("wwr2"),measure)); variables.push_back(RubyContinuousVariable("Var 3",OSArgument::makeDoubleArgument("wwr3"),measure)); variables.push_back(RubyContinuousVariable("Var 4",OSArgument::makeDoubleArgument("wwr4"),measure)); variables.push_back(RubyContinuousVariable("Var 5",OSArgument::makeDoubleArgument("wwr5"),measure)); Problem cProblem("Continuous Problem",variables,runmanager::Workflow()); EXPECT_EQ(5,cProblem.numVariables()); EXPECT_EQ(5,cProblem.numContinuousVariables()); variables.clear(); // mixed problem with three variables, ignorable discrete variable MeasureVector measures; variables.push_back(RubyContinuousVariable("Var 1",OSArgument::makeDoubleArgument("wwr1"),measure)); measures.push_back(RubyMeasure(toPath("script.rb"),FileReferenceType::OSM,FileReferenceType::OSM)); variables.push_back(MeasureGroup("Var 2",measures)); measures.clear(); variables.push_back(RubyContinuousVariable("Var 3",OSArgument::makeDoubleArgument("wwr3"),measure)); Problem mProblem("Mixed Problem",variables,runmanager::Workflow()); EXPECT_EQ(3,mProblem.numVariables()); EXPECT_EQ(2,mProblem.numContinuousVariables()); EXPECT_EQ(1,mProblem.numDiscreteVariables()); EXPECT_EQ(1,mProblem.numStaticTransformations()); variables.clear(); // discrete problem measures.push_back(NullMeasure()); measures.push_back(RubyMeasure(toPath("script1.rb"),FileReferenceType::OSM,FileReferenceType::OSM)); measures.back().cast<RubyMeasure>().addArgument("wwr","0.2"); measures.push_back(RubyMeasure(toPath("script1.rb"),FileReferenceType::OSM,FileReferenceType::OSM)); measures.back().cast<RubyMeasure>().addArgument("wwr","0.4"); variables.push_back(MeasureGroup("Var 1",measures)); measures.clear(); measures.push_back(NullMeasure()); measures.push_back(RubyMeasure(toPath("script2.rb"),FileReferenceType::OSM,FileReferenceType::OSM)); measures.back().cast<RubyMeasure>().addArgument("cop","3.0"); measures.back().cast<RubyMeasure>().addArgument("fan_eff","0.3"); measures.push_back(RubyMeasure(toPath("script2.rb"),FileReferenceType::OSM,FileReferenceType::OSM)); measures.back().cast<RubyMeasure>().addArgument("cop","3.5"); measures.back().cast<RubyMeasure>().addArgument("fan_eff","0.3"); measures.push_back(RubyMeasure(toPath("script2.rb"),FileReferenceType::OSM,FileReferenceType::OSM)); measures.back().cast<RubyMeasure>().addArgument("cop","3.0"); measures.back().cast<RubyMeasure>().addArgument("fan_eff","0.5"); measures.push_back(RubyMeasure(toPath("script2.rb"),FileReferenceType::OSM,FileReferenceType::OSM)); measures.back().cast<RubyMeasure>().addArgument("cop","3.5"); measures.back().cast<RubyMeasure>().addArgument("fan_eff","0.5"); variables.push_back(MeasureGroup("Var 2",measures)); measures.clear(); Problem dProblem("Discrete Problem",variables,runmanager::Workflow()); EXPECT_EQ(2,dProblem.numVariables()); EXPECT_EQ(2,dProblem.numDiscreteVariables()); EXPECT_EQ(0,dProblem.numStaticTransformations()); variables.clear(); // box-behnken DDACEAlgorithmOptions options(DDACEAlgorithmType::box_behnken); DDACEAlgorithm algorithm(options); EXPECT_TRUE(algorithm.isCompatibleProblemType(cProblem)); EXPECT_TRUE(algorithm.isCompatibleProblemType(mProblem)); EXPECT_FALSE(algorithm.isCompatibleProblemType(dProblem)); options.setSamples(DDACEAlgorithmOptions::samplesForBoxBehnken(cProblem)); ASSERT_TRUE(algorithm.ddaceAlgorithmOptions().samples()); EXPECT_EQ(81,algorithm.ddaceAlgorithmOptions().samples().get()); EXPECT_EQ(5,DDACEAlgorithmOptions::samplesForBoxBehnken(mProblem)); EXPECT_EQ(0,DDACEAlgorithmOptions::samplesForBoxBehnken(dProblem)); // central-composite options = DDACEAlgorithmOptions(DDACEAlgorithmType::central_composite); algorithm = DDACEAlgorithm(options); EXPECT_TRUE(algorithm.isCompatibleProblemType(cProblem)); EXPECT_TRUE(algorithm.isCompatibleProblemType(mProblem)); EXPECT_FALSE(algorithm.isCompatibleProblemType(dProblem)); options.setSamples(DDACEAlgorithmOptions::samplesForCentralComposite(cProblem)); ASSERT_TRUE(algorithm.ddaceAlgorithmOptions().samples()); EXPECT_EQ(43,algorithm.ddaceAlgorithmOptions().samples().get()); EXPECT_EQ(9,DDACEAlgorithmOptions::samplesForCentralComposite(mProblem)); EXPECT_EQ(0,DDACEAlgorithmOptions::samplesForCentralComposite(dProblem)); // grid options = DDACEAlgorithmOptions(DDACEAlgorithmType::grid); algorithm = DDACEAlgorithm(options); EXPECT_TRUE(algorithm.isCompatibleProblemType(cProblem)); EXPECT_TRUE(algorithm.isCompatibleProblemType(mProblem)); EXPECT_FALSE(algorithm.isCompatibleProblemType(dProblem)); EXPECT_TRUE(options.setSamplesForGrid(3,cProblem)); ASSERT_TRUE(algorithm.ddaceAlgorithmOptions().symbols()); ASSERT_TRUE(algorithm.ddaceAlgorithmOptions().samples()); EXPECT_EQ(3,algorithm.ddaceAlgorithmOptions().symbols().get()); EXPECT_EQ(243,algorithm.ddaceAlgorithmOptions().samples().get()); EXPECT_TRUE(algorithm.ddaceAlgorithmOptions().setSamplesForGrid(5,mProblem)); ASSERT_TRUE(algorithm.ddaceAlgorithmOptions().symbols()); ASSERT_TRUE(algorithm.ddaceAlgorithmOptions().samples()); EXPECT_EQ(5,algorithm.ddaceAlgorithmOptions().symbols().get()); EXPECT_EQ(25,algorithm.ddaceAlgorithmOptions().samples().get()); EXPECT_FALSE(options.setSamplesForGrid(2,dProblem)); // lhs options = DDACEAlgorithmOptions(DDACEAlgorithmType::lhs); algorithm = DDACEAlgorithm(options); EXPECT_TRUE(algorithm.isCompatibleProblemType(cProblem)); EXPECT_TRUE(algorithm.isCompatibleProblemType(mProblem)); EXPECT_TRUE(algorithm.isCompatibleProblemType(dProblem)); // oa_lhs options = DDACEAlgorithmOptions(DDACEAlgorithmType::oa_lhs); algorithm = DDACEAlgorithm(options); EXPECT_TRUE(algorithm.isCompatibleProblemType(cProblem)); EXPECT_TRUE(algorithm.isCompatibleProblemType(mProblem)); EXPECT_TRUE(algorithm.isCompatibleProblemType(dProblem)); // oas options = DDACEAlgorithmOptions(DDACEAlgorithmType::oas); algorithm = DDACEAlgorithm(options); EXPECT_TRUE(algorithm.isCompatibleProblemType(cProblem)); EXPECT_TRUE(algorithm.isCompatibleProblemType(mProblem)); EXPECT_TRUE(algorithm.isCompatibleProblemType(dProblem)); // random options = DDACEAlgorithmOptions(DDACEAlgorithmType::random); algorithm = DDACEAlgorithm(options); EXPECT_TRUE(algorithm.isCompatibleProblemType(cProblem)); EXPECT_TRUE(algorithm.isCompatibleProblemType(mProblem)); EXPECT_TRUE(algorithm.isCompatibleProblemType(dProblem)); }
TEST_F(AnalysisFixture, DDACEAlgorithmOptions) { // problem with three variables VariableVector variables; BCLMeasure bclMeasure(resourcesPath() / toPath("utilities/BCL/Measures/v2/SetWindowToWallRatioByFacade")); RubyMeasure measure(bclMeasure); variables.push_back(RubyContinuousVariable("Var 1",OSArgument::makeDoubleArgument("wwr1"),measure)); variables.push_back(RubyContinuousVariable("Var 2",OSArgument::makeDoubleArgument("wwr2"),measure)); variables.push_back(RubyContinuousVariable("Var 3",OSArgument::makeDoubleArgument("wwr3"),measure)); Problem problem("Null Problem",variables,runmanager::Workflow()); DDACEAlgorithmOptions options(DDACEAlgorithmType::grid); EXPECT_EQ(DDACEAlgorithmType(DDACEAlgorithmType::grid),options.algorithmType()); EXPECT_FALSE(options.samples()); options.setSamplesForGrid(2,problem); ASSERT_TRUE(options.samples()); EXPECT_EQ(8,options.samples().get()); options.setSamplesForGrid(5,problem); ASSERT_TRUE(options.samples()); EXPECT_EQ(125,options.samples().get()); DDACEAlgorithmOptions optionsClone = options.clone().cast<DDACEAlgorithmOptions>(); // all Attributes should be equivalent but have different UUIDs AttributeVector attributes = options.options(); AttributeVector attributeClones = optionsClone.options(); ASSERT_EQ(attributes.size(),attributeClones.size()); for (unsigned i = 0, n = attributes.size(); i < n; ++i) { EXPECT_TRUE(attributes[i] == attributeClones[i]); EXPECT_FALSE(attributes[i].uuid() == attributeClones[i].uuid()); EXPECT_FALSE(attributes[i].versionUUID() == attributeClones[i].versionUUID()); } options = DDACEAlgorithmOptions(DDACEAlgorithmType::lhs); options.setSeed(891678); options.setSamples(62); ASSERT_TRUE(options.seed()); EXPECT_EQ(891678,options.seed().get()); ASSERT_TRUE(options.samples()); EXPECT_EQ(62,options.samples().get()); EXPECT_FALSE(options.symbols()); options.setSeed(1); ASSERT_TRUE(options.seed()); EXPECT_EQ(1,options.seed().get()); options.clearSeed(); EXPECT_FALSE(options.seed()); options = DDACEAlgorithmOptions(DDACEAlgorithmType::oas); options.setSamplesAndSymbolsForOrthogonalArray(13,1); EXPECT_TRUE(options.seed()); // default is to generate a fixed seed ASSERT_TRUE(options.symbols()); EXPECT_EQ(13,options.symbols().get()); ASSERT_TRUE(options.samples()); EXPECT_EQ(169,options.samples().get()); optionsClone = options.clone().cast<DDACEAlgorithmOptions>(); // all Attributes should be equivalent but have different UUIDs attributes = options.options(); attributeClones = optionsClone.options(); ASSERT_EQ(attributes.size(),attributeClones.size()); for (unsigned i = 0, n = attributes.size(); i < n; ++i) { EXPECT_TRUE(attributes[i] == attributeClones[i]); EXPECT_FALSE(attributes[i].uuid() == attributeClones[i].uuid()); EXPECT_FALSE(attributes[i].versionUUID() == attributeClones[i].versionUUID()); } options.clearSymbols(); EXPECT_FALSE(options.symbols()); EXPECT_TRUE(options.samples()); options.clearSamples(); EXPECT_FALSE(options.samples()); int n = DDACEAlgorithmOptions::samplesForCentralComposite(problem); EXPECT_EQ(15,n); n = DDACEAlgorithmOptions::samplesForBoxBehnken(problem); EXPECT_EQ(13,n); }
openstudio::analysis::Analysis AnalysisFixture::analysis1(AnalysisState state) { // Create problem and analysis Problem problem("My Problem"); BCLMeasure bclMeasure(resourcesPath() / toPath("utilities/BCL/Measures/SetWindowToWallRatioByFacade")); RubyMeasure measure(bclMeasure); // Measure Group StringVector choices; choices.push_back("North"); choices.push_back("South"); choices.push_back("East"); choices.push_back("West"); OSArgument facade = OSArgument::makeChoiceArgument("facade",choices); OSArgument arg = facade.clone(); arg.setValue("South"); measure.setArgument(arg); OSArgument wwr = OSArgument::makeDoubleArgument("wwr"); MeasureVector measures(1u,NullMeasure()); measures.push_back(measure.clone().cast<Measure>()); arg = wwr.clone(); arg.setValue(0.1); measures.back().cast<RubyMeasure>().setArgument(arg); measures.push_back(measure.clone().cast<Measure>()); arg = wwr.clone(); arg.setValue(0.2); measures.back().cast<RubyMeasure>().setArgument(arg); measures.push_back(measure.clone().cast<Measure>()); arg = wwr.clone(); arg.setValue(0.3); measures.back().cast<RubyMeasure>().setArgument(arg); problem.push(MeasureGroup("South Windows",measures)); // Continuous Variables Attached to Arguments arg = facade.clone(); arg.setValue("North"); measure.setArgument(arg); arg = wwr.clone(); RubyContinuousVariable wwrCV("Window to Wall Ratio",arg,measure); wwrCV.setMinimum(0.0); wwrCV.setMaximum(1.0); TriangularDistribution td(0.2,0.0,0.5); wwrCV.setUncertaintyDescription(td); problem.push(wwrCV); OSArgument offset = OSArgument::makeDoubleArgument("offset"); RubyContinuousVariable offsetCV("Offset",offset,measure); offsetCV.setMinimum(0.0); offsetCV.setMaximum(1.5); NormalDistribution nd(0.9,0.05); offsetCV.setUncertaintyDescription(nd); problem.push(offsetCV); // Simulation problem.push(WorkItem(JobType::ModelToIdf)); problem.push(WorkItem(JobType::EnergyPlusPreProcess)); problem.push(WorkItem(JobType::EnergyPlus)); problem.push(WorkItem(JobType::OpenStudioPostProcess)); // Responses LinearFunction response1("Energy Use Intensity", VariableVector(1u,OutputAttributeVariable("EUI","site.eui"))); problem.pushResponse(response1); VariableVector vars; vars.push_back(OutputAttributeVariable("Heating Energy","heating.energy.gas")); vars.push_back(OutputAttributeVariable("Cooling Energy","cooling.energy.elec")); DoubleVector coeffs; coeffs.push_back(1.0); // approx. source factor coeffs.push_back(2.5); // approx. source factor LinearFunction response2("Approximate Source Energy",vars,coeffs); problem.pushResponse(response2); LinearFunction response3("North WWR",VariableVector(1u,wwrCV)); // input variable as output problem.pushResponse(response3); Analysis analysis("My Analysis",problem,FileReferenceType::OSM); if (state == PreRun) { // Add three DataPoints std::vector<QVariant> values; values.push_back(0); values.push_back(0.2); values.push_back(0.9); OptionalDataPoint dataPoint = problem.createDataPoint(values); analysis.addDataPoint(*dataPoint); values[0] = 1; values[1] = 0.21851789; values[2] = 1.1681938; dataPoint = problem.createDataPoint(values); analysis.addDataPoint(*dataPoint); values[0] = 2; values[1] = 0.0; values[2] = 0.581563892; dataPoint = problem.createDataPoint(values); analysis.addDataPoint(*dataPoint); } else { // state == PostRun // Add one complete DataPoint std::vector<QVariant> values; values.push_back(1); values.push_back(0.3); values.push_back(0.9); DoubleVector responseValues; responseValues.push_back(58.281967); responseValues.push_back(718952.281); responseValues.push_back(0.3); TagVector tags; tags.push_back(Tag("custom")); tags.push_back(Tag("faked")); // attributes AttributeVector attributes; attributes.push_back(Attribute("electricity.Cooling",281.281567,"kWh")); attributes.push_back(Attribute("electricity.Lighting",19206.291876,"kWh")); attributes.push_back(Attribute("electricity.Equipment",5112.125718,"kWh")); attributes = AttributeVector(1u,Attribute("enduses.electric",attributes)); attributes.push_back(Attribute("eui",createQuantity(128.21689,"kBtu/ft^2").get())); // complete job // 1. get vector of work items std::vector<WorkItem> workItems; // 0 workItems.push_back(problem.variables()[0].cast<MeasureGroup>().createWorkItem(QVariant(1), toPath(rubyOpenStudioDir()))); RubyContinuousVariable rcv = problem.variables()[1].cast<RubyContinuousVariable>(); RubyMeasure rm = rcv.measure(); OSArgument arg = rcv.argument().clone(); arg.setValue(values[1].toDouble()); rm.setArgument(arg); rcv = problem.variables()[2].cast<RubyContinuousVariable>(); arg = rcv.argument().clone(); arg.setValue(values[2].toDouble()); rm.setArgument(arg); // 1 workItems.push_back(rm.createWorkItem(toPath(rubyOpenStudioDir()))); // 2 workItems.push_back(WorkItem(JobType::ModelToIdf)); // 3 workItems.push_back(WorkItem(JobType::EnergyPlusPreProcess)); // 4 workItems.push_back(WorkItem(JobType::EnergyPlus)); // 5 workItems.push_back(WorkItem(JobType::OpenStudioPostProcess)); // 2. step through work items and create jobs with results WorkItem wi = workItems[5]; std::vector<FileInfo> inFiles = wi.files.files(); inFiles.push_back(FileInfo("eplusout.sql", DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,33,32)), "", toPath("myProject/fakeDataPoint/75-OpenStudioPostProcess-0/eplusout.sql"))); Files inFilesObject(inFiles); std::vector<std::pair<ErrorType, std::string> > errors; errors.push_back(std::make_pair(ErrorType::Info,"Post-process completed successfully.")); JobErrors errorsObject(OSResultValue::Success,errors); std::vector<FileInfo> outFiles; outFiles.push_back(FileInfo("report.xml", DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,34,21)), "", toPath("myProject/fakeDataPoint/75-OpenStudioPostProcess-0/report.xml"))); Files outFilesObject(outFiles); Job job = JobFactory::createJob( wi.type, wi.tools, wi.params, inFilesObject, std::vector<openstudio::URLSearchPath>(), false, createUUID(), JobState( DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,34,21)), errorsObject, outFilesObject, AdvancedStatus(), openstudio::path()) ); // OpenStudioPostProcess Job jobLast = job; wi = workItems[4]; inFiles = wi.files.files(); inFiles.push_back(FileInfo("in.idf", DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,23,05)), "", toPath("myProject/fakeDataPoint/74-EnergyPlus-0/in.idf"))); inFilesObject = Files(inFiles); errors.clear(); errors.push_back(std::make_pair(ErrorType::Warning,"ENERGYPLUS WARNING: ...")); errors.push_back(std::make_pair(ErrorType::Warning,"ENERGYPLUS WARNING: ...")); errors.push_back(std::make_pair(ErrorType::Warning,"ENERGYPLUS WARNING: ...")); errorsObject = JobErrors(OSResultValue::Success,errors); outFiles.clear(); outFiles.push_back(FileInfo("eplusout.sql", DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,33,32)), "", toPath("myProject/fakeDataPoint/74-EnergyPlus-0/eplusout.sql"))); outFiles.push_back(FileInfo("eplusout.err", DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,33,34)), "", toPath("myProject/fakeDataPoint/74-EnergyPlus-0/eplusout.err"))); outFilesObject = Files(outFiles); job = JobFactory::createJob( wi.type, wi.tools, wi.params, inFilesObject, std::vector<openstudio::URLSearchPath>(), false, createUUID(), JobState( DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,33,42)), errorsObject, outFilesObject, AdvancedStatus(), openstudio::path()) ); // EnergyPlus job.addChild(jobLast); jobLast = job; wi = workItems[3]; inFiles = wi.files.files(); inFiles.push_back(FileInfo("in.idf", DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,22,30)), "", toPath("myProject/fakeDataPoint/73-EnergyPlusPreProcess-0/in.idf"))); inFilesObject = Files(inFiles); errors.clear(); errorsObject = JobErrors(OSResultValue::Success,errors); outFiles.clear(); outFiles.push_back(FileInfo("out.idf", DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,23,05)), "", toPath("myProject/fakeDataPoint/73-EnergyPlusPreProcess-0/out.idf"))); outFilesObject = Files(outFiles); job = JobFactory::createJob( wi.type, wi.tools, wi.params, inFilesObject, std::vector<openstudio::URLSearchPath>(), false, createUUID(), JobState( DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,23,12)), errorsObject, outFilesObject, AdvancedStatus(), openstudio::path()) ); // EnergyPlusPreProcess job.addChild(jobLast); jobLast = job; wi = workItems[2]; inFiles = wi.files.files(); inFiles.push_back(FileInfo("in.osm", DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,22,01)), "", toPath("myProject/fakeDataPoint/72-ModelToIdf-0/in.osm"))); inFilesObject = Files(inFiles); errors.clear(); errors.push_back(std::make_pair(ErrorType::Info,"Did not find ScheduleTypeLimits for Schedule ...")); errors.push_back(std::make_pair(ErrorType::Warning,"Unexpectedly did not find a child object of a certain type, replaced with a default one.")); errorsObject = JobErrors(OSResultValue::Success,errors); outFiles.clear(); outFiles.push_back(FileInfo("out.idf", DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,22,30)), "", toPath("myProject/fakeDataPoint/72-ModelToIdf-0/out.idf"))); outFilesObject = Files(outFiles); job = JobFactory::createJob( wi.type, wi.tools, wi.params, inFilesObject, std::vector<openstudio::URLSearchPath>(), false, createUUID(), JobState( DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,22,32)), errorsObject, outFilesObject, AdvancedStatus(), openstudio::path()) ); // ModelToIdf job.addChild(jobLast); jobLast = job; wi = workItems[1]; errors.clear(); errors.push_back(std::make_pair(ErrorType::InitialCondition,"Started with a window to wall ratio of ...")); errors.push_back(std::make_pair(ErrorType::FinalCondition,"Set the window to wall ratio ...")); errorsObject = JobErrors(OSResultValue::Success,errors); outFiles.clear(); outFilesObject = Files(outFiles); wi.params.append("outdir","myProject/fakeDataPoint/"); job = JobFactory::createJob( wi.type, wi.tools, wi.params, wi.files, std::vector<openstudio::URLSearchPath>(), false, createUUID(), JobState( DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,21,52)), errorsObject, outFilesObject, AdvancedStatus(), openstudio::path()) ); // Variables 2 & 3 job.addChild(jobLast); jobLast = job; wi = workItems[0]; errors.clear(); errors.push_back(std::make_pair(ErrorType::InitialCondition,"Started with a window to wall ratio of ...")); errors.push_back(std::make_pair(ErrorType::FinalCondition,"Set the window to wall ratio ...")); errorsObject = JobErrors(OSResultValue::Success,errors); outFiles.clear(); outFilesObject = Files(outFiles); // add outdir job param JobParams params = wi.params; params.append("outdir","myProject/fakeDataPoint"); job = JobFactory::createJob( wi.type, wi.tools, params, wi.files, std::vector<openstudio::URLSearchPath>(), false, createUUID(), JobState( DateTime(Date(MonthOfYear::Mar,21,2018),Time(0,8,21,10)), errorsObject, outFilesObject, AdvancedStatus(), openstudio::path()) ); // Variable 1 job.addChild(jobLast); DataPoint dataPoint(createUUID(), createUUID(), "fakeDataPoint", "Fake Data Point", "Demonstrating json serialization of complete DataPoint.", problem, true, false, true, DataPointRunType::Local, values, responseValues, toPath("myProject/fakeDataPoint/"), FileReference(toPath("myProject/fakeDataPoint/71-Ruby-0/out.osm")), FileReference(toPath("myProject/fakeDataPoint/72-ModelToIdf-0/out.idf")), FileReference(toPath("myProject/fakeDataPoint/74-EnergyPlus-0/eplusout.sql")), FileReferenceVector(1u,FileReference(toPath("myProject/fakeDataPoint/75-OpenStudioPostProcess-0/report.xml"))), job, std::vector<openstudio::path>(), tags, attributes); EXPECT_TRUE(analysis.addDataPoint(dataPoint)); } return analysis; }
TEST_F(ProjectFixture, ProblemRecord) { //Logger::instance().logLevel(Debug); openstudio::path rubyLibDirPath = openstudio::toPath(rubyLibDir()); openstudio::path perturbScript = rubyLibDirPath/openstudio::toPath("openstudio/runmanager/rubyscripts/PerturbObject.rb"); // Workflow Workflow workflow; // Variables VariableVector variables; // Measures MeasureVector perturbations1; MeasureVector perturbations2; // Discrete Variable Records InputVariableRecordVector measureGroupRecords; { // Problem Problem problem("0 Variables",variables,workflow); // Project Database ProjectDatabase database = getCleanDatabase("ProblemRecord"); // Problem Record ProblemRecord problemRecord = ProblemRecord::factoryFromProblem(problem,database); InputVariableRecordVector measureGroupRecords = problemRecord.inputVariableRecords(); EXPECT_EQ(0u,measureGroupRecords.size()); } { perturbations1.push_back(NullMeasure()); variables.push_back(analysis::MeasureGroup("",perturbations1)); // Problem Problem problem("perturbations1",variables,workflow); // Project Database ProjectDatabase database = getCleanDatabase("ProblemRecord"); // Problem Record ProblemRecord problemRecord = ProblemRecord::factoryFromProblem(problem,database); measureGroupRecords = problemRecord.inputVariableRecords(); EXPECT_EQ(1u,measureGroupRecords.size()); // Discrete Variable Record MeasureGroupRecord measureGroupRecord = measureGroupRecords.at(0).cast<MeasureGroupRecord>(); EXPECT_EQ(1u,measureGroupRecord.measureRecordIds(true).size()); EXPECT_EQ(1u,measureGroupRecord.measureRecords(true).size()); } { variables.push_back(MeasureGroup("Wall Construction",perturbations1)); // Problem Problem problem("perturbations1",variables,workflow); // Project Database ProjectDatabase database = getCleanDatabase("ProblemRecord"); // Problem Record ProblemRecord problemRecord = ProblemRecord::factoryFromProblem(problem,database); measureGroupRecords = problemRecord.inputVariableRecords(); EXPECT_EQ(2u,measureGroupRecords.size()); // Discrete Variable Record MeasureGroupRecord variable1 = measureGroupRecords.at(0).cast<MeasureGroupRecord>(); EXPECT_EQ(static_cast<unsigned>(1), variable1.measureRecords(true).size()); EXPECT_EQ(static_cast<unsigned>(1), variable1.measureRecords(false).size()); EXPECT_EQ(static_cast<unsigned>(2), problemRecord.inputVariableRecords().size()); } { perturbations2.push_back(NullMeasure()); variables.push_back(MeasureGroup("Roof Construction",perturbations2)); // Problem Problem problem("perturbations2",variables,workflow); // Project Database ProjectDatabase database = getCleanDatabase("ProblemRecord"); // Problem Record ProblemRecord problemRecord = ProblemRecord::factoryFromProblem(problem,database); measureGroupRecords = problemRecord.inputVariableRecords(); EXPECT_EQ(3u,measureGroupRecords.size()); // Discrete Variable Record MeasureGroupRecord variable1 = measureGroupRecords.at(0).cast<MeasureGroupRecord>(); MeasureGroupRecord variable2 = measureGroupRecords.at(0).cast<MeasureGroupRecord>(); MeasureGroupRecord variable3 = measureGroupRecords.at(0).cast<MeasureGroupRecord>(); EXPECT_EQ(static_cast<size_t>(1), variable1.measureRecords(true).size()); EXPECT_EQ(static_cast<size_t>(1), variable1.measureRecords(false).size()); EXPECT_EQ(static_cast<size_t>(3), problemRecord.inputVariableRecords().size()); UUID uuid1; UUID versionUUID1; NullMeasure nullMeasure1(uuid1,versionUUID1,"","","",true); NullMeasureRecord nullMeasureRecord1(nullMeasure1,variable1,0); EXPECT_EQ(static_cast<unsigned>(2), variable1.measureRecords(true).size()); EXPECT_EQ(static_cast<unsigned>(2), variable1.measureRecords(false).size()); EXPECT_EQ(static_cast<unsigned>(2), variable2.measureRecords(true).size()); EXPECT_EQ(static_cast<unsigned>(2), variable2.measureRecords(false).size()); UUID uuid2; UUID versionUUID2; NullMeasure nullMeasure2(uuid2,versionUUID2,"","","",true); NullMeasureRecord nullMeasureRecord2(nullMeasure2,variable1,0); EXPECT_EQ(static_cast<unsigned>(2), variable1.measureRecords(true).size()); EXPECT_EQ(static_cast<unsigned>(2), variable1.measureRecords(false).size()); EXPECT_EQ(static_cast<unsigned>(2), variable2.measureRecords(true).size()); EXPECT_EQ(static_cast<unsigned>(2), variable2.measureRecords(false).size()); MeasureVector perturbations; MeasureGroup measureGroup("Wall Construction",perturbations); MeasureGroupRecord measureGroupRecord(measureGroup, problemRecord,0); openstudio::path rubyPath = resourcesPath() / openstudio::toPath("project/rubyscripts/*.rb"); openstudio::path perturbScript = rubyPath/openstudio::toPath("openstudio/runmanager/rubyscripts/PerturbObject.rb"); RubyMeasure rubyMeasure(perturbScript,FileReferenceType::OSM,FileReferenceType::OSM); RubyMeasureRecord rubyMeasureRecord1(rubyMeasure,measureGroupRecord,0); EXPECT_EQ(static_cast<unsigned>(1), measureGroupRecord.numMeasures(true)); EXPECT_EQ(static_cast<unsigned>(1), measureGroupRecord.measureRecordIds(true).size()); EXPECT_EQ(static_cast<unsigned>(1), measureGroupRecord.measureRecords(true).size()); RubyMeasureRecord rubyMeasureRecord(rubyMeasure,measureGroupRecord,0); EXPECT_EQ(static_cast<unsigned>(1), measureGroupRecord.numMeasures(true)); EXPECT_EQ(static_cast<unsigned>(1), measureGroupRecord.measureRecordIds(true).size()); EXPECT_EQ(rubyMeasureRecord.id(), measureGroupRecord.measureRecordIds(true)[0]); EXPECT_EQ(static_cast<unsigned>(1), measureGroupRecord.measureRecords(true).size()); EXPECT_EQ(rubyMeasureRecord.handle(), measureGroupRecord.measureRecords(true)[0].handle()); } }
TEST_F(AnalysisFixture, Problem_Constructors) { VariableVector variables; MeasureVector measures; runmanager::Workflow workflow; // almost-default constructor Problem problem("Problem",variables,workflow); EXPECT_EQ(0,problem.numVariables()); OptionalInt combinatorialSize = problem.combinatorialSize(true); ASSERT_TRUE(combinatorialSize); EXPECT_EQ(0,*combinatorialSize); // variables with consistent file types variables.clear(); measures.clear(); measures.push_back(NullMeasure()); openstudio::path rubyScriptPath = toPath(rubyLibDir()) / toPath("openstudio/runmanager/rubyscripts/PerturbObject.rb"); measures.push_back(RubyMeasure(rubyScriptPath, FileReferenceType::OSM, FileReferenceType::OSM)); measures.push_back(RubyMeasure(rubyScriptPath, FileReferenceType::OSM, FileReferenceType::OSM)); variables.push_back(MeasureGroup("Variable 1",measures)); measures.clear(); measures.push_back(RubyMeasure(rubyScriptPath, FileReferenceType::OSM, FileReferenceType::IDF)); variables.push_back(MeasureGroup("Variable 2",measures)); measures.clear(); measures.push_back(NullMeasure()); measures.push_back(RubyMeasure(rubyScriptPath, FileReferenceType::IDF, FileReferenceType::IDF)); variables.push_back(MeasureGroup("Variable 3",measures)); problem = Problem("Problem",variables,workflow); EXPECT_EQ(3,problem.numVariables()); EXPECT_EQ(6,problem.combinatorialSize(true).get()); // variables with inconistent file types variables.clear(); measures.clear(); measures.push_back(NullMeasure()); measures.push_back(RubyMeasure(rubyScriptPath, FileReferenceType::OSM, FileReferenceType::OSM)); measures.push_back(RubyMeasure(rubyScriptPath, FileReferenceType::OSM, FileReferenceType::OSM)); variables.push_back(MeasureGroup("Variable 1",measures)); measures.clear(); measures.push_back(NullMeasure()); measures.push_back(RubyMeasure(rubyScriptPath, FileReferenceType::IDF, FileReferenceType::IDF)); variables.push_back(MeasureGroup("Variable 2",measures)); EXPECT_THROW(Problem("Problem",variables,workflow),std::exception); // variables and non-null workflow with consistent file types variables.clear(); measures.clear(); measures.push_back(NullMeasure()); measures.push_back(RubyMeasure(rubyScriptPath, FileReferenceType::IDF, FileReferenceType::IDF)); variables.push_back(MeasureGroup("Variable 1",measures)); workflow = runmanager::Workflow(); workflow.addJob(openstudio::runmanager::JobType::EnergyPlus); problem = Problem("Problem",variables,workflow); problem.setDisplayName("Display Name"); problem.setDescription("long winded description"); EXPECT_EQ(1,problem.numVariables()); EXPECT_EQ(2,problem.combinatorialSize(true).get()); // deserialization Problem problemCopy(problem.uuid(), problem.versionUUID(), problem.name(), problem.displayName(), problem.description(), problem.workflow(), problem.responses()); EXPECT_FALSE(problem == problemCopy); // different impls EXPECT_TRUE(problem.uuid() == problemCopy.uuid()); EXPECT_TRUE(problem.versionUUID() == problemCopy.versionUUID()); EXPECT_EQ(problem.name(),problemCopy.name()); EXPECT_EQ(problem.displayName(),problemCopy.displayName()); EXPECT_EQ(problem.description(),problemCopy.description()); EXPECT_TRUE(problem.workflow() == problemCopy.workflow()); // variables and non-null workflow with inconsistent file types workflow = runmanager::Workflow(); workflow.addJob(openstudio::runmanager::JobType::ModelToIdf); workflow.addJob(openstudio::runmanager::JobType::EnergyPlus); EXPECT_THROW(Problem("Problem",variables,workflow),std::exception); }
TEST_F(AnalysisFixture, Problem_FileTypesAreCompatible_ExistingMeasureGroup) { // expected behavior when discrete variable already contains measures // test with BCLMeasure first. verify with RubyMeasure. // create problem VariableVector variables; variables.push_back( MeasureGroup("Model Variable 1", MeasureVector(1u,RubyMeasure(toPath("modelUserScript.rb"), FileReferenceType::OSM, FileReferenceType::OSM, true)))); variables.back().cast<MeasureGroup>().insert(0,NullMeasure()); // 2 variables.push_back( MeasureGroup("Translation Variable 1", MeasureVector(1u,RubyMeasure(toPath("translationUserScript.rb"), FileReferenceType::OSM, FileReferenceType::IDF, true)))); // 3 variables.push_back( MeasureGroup("Workspace Variable 1", MeasureVector(1u,RubyMeasure(toPath("workspaceUserScript.rb"), FileReferenceType::IDF, FileReferenceType::IDF, true)))); variables.back().cast<MeasureGroup>().insert(0,NullMeasure()); runmanager::Workflow workflow; workflow.addJob(runmanager::JobType::EnergyPlus); Problem problem("Problem",variables,workflow); // create measure to be pushed onto a variable openstudio::path dir = resourcesPath() / toPath("/utilities/BCL/Measures/v2/SetWindowToWallRatioByFacade"); BCLMeasure bclMeasure = BCLMeasure::load(dir).get(); EXPECT_EQ(FileReferenceType(FileReferenceType::OSM),bclMeasure.inputFileType()); EXPECT_EQ(FileReferenceType(FileReferenceType::OSM),bclMeasure.outputFileType()); RubyMeasure measure(bclMeasure); ASSERT_EQ(3,problem.numVariables()); // can be added to variable 0 (OSM) WorkflowStep step = problem.workflow()[0]; InputVariable var = step.inputVariable(); EXPECT_EQ(2u,var.cast<MeasureGroup>().numMeasures(false)); EXPECT_TRUE(problem.fileTypesAreCompatible(step, measure.inputFileType(), measure.outputFileType())); EXPECT_TRUE(var.cast<MeasureGroup>().push(measure)); EXPECT_EQ(3u,var.cast<MeasureGroup>().numMeasures(false)); // cannot be added to variable 1 (translation) step = problem.workflow()[1]; var = step.inputVariable(); EXPECT_EQ(1u,var.cast<MeasureGroup>().numMeasures(false)); EXPECT_FALSE(problem.fileTypesAreCompatible(step, measure.inputFileType(), measure.outputFileType())); EXPECT_FALSE(var.cast<MeasureGroup>().push(measure)); EXPECT_EQ(1u,var.cast<MeasureGroup>().numMeasures(false)); // cannot be added to variable 2 (IDF) step = problem.variables()[2]; var = step.inputVariable(); EXPECT_EQ(2u,var.cast<MeasureGroup>().numMeasures(false)); EXPECT_FALSE(problem.fileTypesAreCompatible(step, measure.inputFileType(), measure.outputFileType())); EXPECT_FALSE(var.cast<MeasureGroup>().push(measure)); EXPECT_EQ(2u,var.cast<MeasureGroup>().numMeasures(false)); }
TEST_F(AnalysisFixture, Problem_FileTypesAreCompatible_NewMeasureGroup) { // ok to insert null-only discrete variable anywhere in the chain // (between null-model, model-model, idf-idf, idf-workflow) VariableVector variables; // 0 variables.push_back( MeasureGroup("Null Variable 1", MeasureVector(1u,NullMeasure()))); // 1 variables.push_back( MeasureGroup("Model Variable 1", MeasureVector(1u,RubyMeasure(toPath("modelUserScript.rb"), FileReferenceType::OSM, FileReferenceType::OSM, true)))); // 2 variables.push_back( MeasureGroup("Translation Variable 1", MeasureVector(1u,RubyMeasure(toPath("translationUserScript.rb"), FileReferenceType::OSM, FileReferenceType::IDF, true)))); // 3 variables.push_back( MeasureGroup("Workspace Variable 1", MeasureVector(1u,RubyMeasure(toPath("workspaceUserScript.rb"), FileReferenceType::IDF, FileReferenceType::IDF, true)))); runmanager::Workflow workflow; workflow.addJob(runmanager::JobType::EnergyPlus); Problem problem("Problem 1",variables,workflow); MeasureGroup newVar("New Discrete Variable", MeasureVector(1u,NullMeasure())); EXPECT_TRUE(problem.insert(4,newVar.clone().cast<InputVariable>())); ASSERT_EQ(5,problem.numVariables()); EXPECT_EQ("New Discrete Variable",problem.variables()[4].name()); EXPECT_TRUE(problem.insert(3,newVar.clone().cast<InputVariable>())); EXPECT_EQ(6,problem.numVariables()); ASSERT_GE(problem.numVariables(),5); EXPECT_EQ("Translation Variable 1",problem.variables()[2].name()); EXPECT_EQ("New Discrete Variable",problem.variables()[3].name()); EXPECT_EQ("Workspace Variable 1",problem.variables()[4].name()); EXPECT_TRUE(problem.insert(2,newVar.clone().cast<InputVariable>())); EXPECT_TRUE(problem.insert(1,newVar.clone().cast<InputVariable>())); EXPECT_TRUE(problem.insert(0,newVar.clone().cast<InputVariable>())); EXPECT_EQ(9,problem.numVariables()); variables = castVector<Variable>(problem.variables()); for (int i = 0, n = problem.numVariables(); i < n; ++i) { if (i % 2 == 0) { EXPECT_EQ("New Discrete Variable",variables[i].name()); } else { EXPECT_NE("New Discrete Variable",variables[i].name()); } } // (between null-idf, idf-idf, idf-workflow) variables.clear(); // 0 variables.push_back( MeasureGroup("Null Variable 1", MeasureVector(1u,NullMeasure()))); // 1 variables.push_back( MeasureGroup("Workspace Variable 1", MeasureVector(1u,RubyMeasure(toPath("workspaceUserScript.rb"), FileReferenceType::IDF, FileReferenceType::IDF, true)))); // 2 variables.push_back( MeasureGroup("Workspace Variable 2", MeasureVector(1u,RubyMeasure(toPath("workspaceUserScript.rb"), FileReferenceType::IDF, FileReferenceType::IDF, true)))); problem = Problem("Problem 2",variables,workflow); EXPECT_TRUE(problem.insert(3,newVar.clone().cast<InputVariable>())); EXPECT_TRUE(problem.insert(2,newVar.clone().cast<InputVariable>())); EXPECT_TRUE(problem.insert(1,newVar.clone().cast<InputVariable>())); EXPECT_TRUE(problem.insert(0,newVar.clone().cast<InputVariable>())); EXPECT_EQ(7,problem.numVariables()); variables = castVector<Variable>(problem.variables()); for (int i = 0, n = problem.numVariables(); i < n; ++i) { if (i % 2 == 0) { EXPECT_EQ("New Discrete Variable",variables[i].name()); } else { EXPECT_NE("New Discrete Variable",variables[i].name()); } } // expected behavior for then adding first measure // test with BCLMeasure first. verify with RubyMeasure. openstudio::path dir = resourcesPath() / toPath("/utilities/BCL/Measures/v2/SetWindowToWallRatioByFacade"); BCLMeasure bclMeasure = BCLMeasure::load(dir).get(); EXPECT_EQ(FileReferenceType(FileReferenceType::OSM),bclMeasure.inputFileType()); EXPECT_EQ(FileReferenceType(FileReferenceType::OSM),bclMeasure.outputFileType()); RubyMeasure measure(bclMeasure); // have idf-only problem with two null variables at the top // try to add measures to first variable MeasureGroup firstVariable = problem.variables()[0].cast<MeasureGroup>(); ASSERT_TRUE(firstVariable.parent()); WorkflowStep step0 = problem.workflow()[0]; EXPECT_TRUE(firstVariable.parent().get() == step0); EXPECT_EQ(1u,firstVariable.numMeasures(false)); EXPECT_FALSE(problem.fileTypesAreCompatible(firstVariable, measure.inputFileType(), measure.outputFileType())); ASSERT_TRUE(firstVariable.parent()); EXPECT_TRUE(firstVariable.parent().get() == problem.workflow()[0]); EXPECT_TRUE(problem.workflow()[0] == step0); EXPECT_FALSE(firstVariable.push(measure)); EXPECT_EQ(1u,firstVariable.numMeasures(false)); // make second variable a translation variable MeasureGroup secondVariable = problem.variables()[1].cast<MeasureGroup>(); EXPECT_FALSE(secondVariable.push(RubyMeasure(toPath("myTranslationScript.rb"), FileReferenceType::OSM, FileReferenceType::IDF))); secondVariable.erase(secondVariable.measures(false)[0]); EXPECT_TRUE(secondVariable.push(RubyMeasure(toPath("myTranslationScript.rb"), FileReferenceType::OSM, FileReferenceType::IDF))); // now should be able to add OSM measure EXPECT_TRUE(problem.fileTypesAreCompatible(firstVariable, measure.inputFileType(), measure.outputFileType())); EXPECT_TRUE(firstVariable.push(measure)); EXPECT_EQ(2u,firstVariable.numMeasures(false)); }
void Stepper::unregisterProcess( Process* aProcess ) { ProcessVector::iterator ip( std::find( theProcessVector.begin(), theProcessVector.end(), aProcess ) ); if( ip == theProcessVector.end() ) { THROW_EXCEPTION_INSIDE( NotFound, asString() + ": Failed to dissociate [" + aProcess->asString() + "] (no such Process is " "associated to this stepper)" ); } typedef std::set< Variable* > VariableSet; VariableSet aVarSet; Process::VariableReferenceVector const& aVarRefVector( aProcess->getVariableReferenceVector() ); std::transform( aVarRefVector.begin(), aVarRefVector.end(), inserter( aVarSet, aVarSet.begin() ), std::mem_fun_ref( &VariableReference::getVariable ) ); VariableVector aNewVector; VariableVector::size_type aReadWriteVariableOffset, aReadOnlyVariableOffset; for( VariableVector::iterator i( theVariableVector.begin() ), e( theVariableVector.begin() + theReadWriteVariableOffset ); i != e; ++i ) { VariableSet::iterator j( aVarSet.find( *i ) ); if ( j != aVarSet.end() ) aVarSet.erase( j ); else aNewVector.push_back( *i ); } aReadWriteVariableOffset = aNewVector.size(); for( VariableVector::iterator i( theVariableVector.begin() + theReadWriteVariableOffset ), e( theVariableVector.begin() + theReadOnlyVariableOffset ); i != e; ++i ) { VariableSet::iterator j( aVarSet.find( *i ) ); if ( j != aVarSet.end() ) aVarSet.erase( j ); else aNewVector.push_back( *i ); } aReadOnlyVariableOffset = aNewVector.size(); for( VariableVector::iterator i( theVariableVector.begin() + theReadOnlyVariableOffset ), e( theVariableVector.end() ); i != e; ++i ) { VariableSet::iterator j( aVarSet.find( *i ) ); if ( j != aVarSet.end() ) aVarSet.erase( j ); else aNewVector.push_back( *i ); } theVariableVector.swap( aNewVector ); theReadWriteVariableOffset = aReadWriteVariableOffset; theReadOnlyVariableOffset = aReadOnlyVariableOffset; theProcessVector.erase( ip ); }
TEST_F(AnalysisFixture, SequentialSearch) { // define dummy problem VariableVector variables; std::stringstream ss; for (int i = 0; i < 5; ++i) { MeasureVector measures; measures.push_back(NullMeasure()); measures.push_back(RubyMeasure(toPath("in.rb"),FileReferenceType::OSM,FileReferenceType::OSM)); ss << "var " << i + 1; variables.push_back(MeasureGroup(ss.str(),measures)); ss.str(""); } FunctionVector functions; functions.push_back(LinearFunction("",VariableVector(1u,OutputAttributeContinuousVariable("f1","f1")))); functions.push_back(LinearFunction("",VariableVector(1u,OutputAttributeContinuousVariable("f2","f2")))); OptimizationProblem problem("By-Hand Problem",functions,variables,runmanager::Workflow()); // solve dummy problem and check results SequentialSearch algorithm(SequentialSearchOptions(0)); FileReference seed(toPath("in.osm")); Analysis analysis("By-Hand Analysis",problem,algorithm,seed); int numAdded = algorithm.createNextIteration(analysis); EXPECT_EQ(1,numAdded); OptimizationDataPointVector nextIteration = castVector<OptimizationDataPoint>(analysis.dataPointsToQueue()); EXPECT_EQ(1u,nextIteration.size()); while (!nextIteration.empty()) { int n = analysis.dataPoints().size(); LOG(Debug,"Conducting iteration " << algorithm.iter() << " of Sequential Search."); OptimizationDataPointVector completeDataPoints = castVector<OptimizationDataPoint>(analysis.completeDataPoints()); OptimizationDataPointVector currentDataPoints = castVector<OptimizationDataPoint>(analysis.getDataPoints("current")); EXPECT_EQ(1u,currentDataPoints.size()); ASSERT_FALSE(currentDataPoints.empty()); EXPECT_EQ(unsigned(algorithm.iter()),analysis.getDataPoints("explored").size()); if (algorithm.iter() == 0) { EXPECT_EQ(1,n); EXPECT_EQ(0u,completeDataPoints.size()); } else if (algorithm.iter() == 1) { EXPECT_DOUBLE_EQ(20.0,currentDataPoints[0].objectiveValues()[0]); EXPECT_DOUBLE_EQ(20.0,currentDataPoints[0].objectiveValues()[1]); EXPECT_EQ(6,n); EXPECT_EQ(1u,completeDataPoints.size()); EXPECT_TRUE(currentDataPoints[0] == completeDataPoints[0]); EXPECT_TRUE(completeDataPoints[0].isTag("curve0")); EXPECT_TRUE(completeDataPoints[0].isTag("current")); EXPECT_TRUE(completeDataPoints[0].isTag("explored")); EXPECT_EQ(5u,nextIteration.size()); } else if (algorithm.iter() == 2) { EXPECT_DOUBLE_EQ(17.0,currentDataPoints[0].objectiveValues()[0]); EXPECT_DOUBLE_EQ(19.0,currentDataPoints[0].objectiveValues()[1]); EXPECT_EQ(10,n); EXPECT_EQ(6u,completeDataPoints.size()); EXPECT_EQ(2u,analysis.getDataPoints("curve0").size()); EXPECT_EQ(4u,nextIteration.size()); } else if (algorithm.iter() == 3) { EXPECT_DOUBLE_EQ(16.0,currentDataPoints[0].objectiveValues()[0]); EXPECT_DOUBLE_EQ(16.0,currentDataPoints[0].objectiveValues()[1]); EXPECT_EQ(13,n); EXPECT_EQ(10u,completeDataPoints.size()); EXPECT_EQ(3u,analysis.getDataPoints("curve0").size()); EXPECT_EQ(3u,nextIteration.size()); } else if (algorithm.iter() == 4) { // backtracking EXPECT_DOUBLE_EQ(15.0,currentDataPoints[0].objectiveValues()[0]); EXPECT_DOUBLE_EQ(19.0,currentDataPoints[0].objectiveValues()[1]); EXPECT_EQ(16,n); EXPECT_EQ(13u,completeDataPoints.size()); EXPECT_EQ(2u,analysis.getDataPoints("curve0").size()); EXPECT_EQ(3u,nextIteration.size()); } else if (algorithm.iter() == 5) { // backtracking EXPECT_DOUBLE_EQ(18.0,currentDataPoints[0].objectiveValues()[0]); EXPECT_DOUBLE_EQ(20.0,currentDataPoints[0].objectiveValues()[1]); EXPECT_EQ(18,n); EXPECT_EQ(16u,completeDataPoints.size()); EXPECT_EQ(2u,analysis.getDataPoints("curve0").size()); EXPECT_EQ(2u,nextIteration.size()); } else if (algorithm.iter() == 6) { EXPECT_DOUBLE_EQ(17.0,currentDataPoints[0].objectiveValues()[0]); EXPECT_DOUBLE_EQ(14.0,currentDataPoints[0].objectiveValues()[1]); EXPECT_EQ(20,n); EXPECT_EQ(18u,completeDataPoints.size()); EXPECT_EQ(5u,analysis.getDataPoints("curve0").size()); EXPECT_EQ(2u,nextIteration.size()); } else if (algorithm.iter() == 7) { EXPECT_DOUBLE_EQ(20.0,currentDataPoints[0].objectiveValues()[0]); EXPECT_DOUBLE_EQ(12.0,currentDataPoints[0].objectiveValues()[1]); EXPECT_EQ(23,n); EXPECT_EQ(20u,completeDataPoints.size()); EXPECT_EQ(6u,analysis.getDataPoints("curve0").size()); EXPECT_EQ(3u,nextIteration.size()); } EXPECT_EQ(static_cast<size_t>(n),completeDataPoints.size() + nextIteration.size()); for (const OptimizationDataPoint& point : nextIteration) { std::vector<QVariant> values = point.variableValues(); DoubleVector objectiveValues = getObjectiveValues(values); for (int i = 0; i < 5; ++i) { int value = values[i].toInt(); if (value == 0) { ss << " "; } else { EXPECT_EQ(1,value); ss << i + 1 << " "; } } ss << ": " << objectiveValues[0] << ", " << objectiveValues[1]; LOG(Debug,ss.str()); ss.str(""); completeDataPoints.push_back(OptimizationDataPoint(point.uuid(), createUUID(), "","","", problem, true, false, true, DataPointRunType::Local, values, DoubleVector(), objectiveValues, openstudio::path(), boost::none, boost::none, boost::none, boost::none, std::vector<openstudio::path>(), point.tags(), point.outputAttributes())); // DLM: Elaine is this ok? } EXPECT_EQ(static_cast<size_t>(n),completeDataPoints.size()); analysis = Analysis(analysis.uuid(), createUUID(), analysis.name(), analysis.displayName(), analysis.description(), problem, algorithm, seed, boost::none, castVector<DataPoint>(completeDataPoints), false, false); algorithm.createNextIteration(analysis); nextIteration = castVector<OptimizationDataPoint>(analysis.dataPointsToQueue()); } EXPECT_EQ(23u,analysis.successfulDataPoints().size()); OptimizationDataPointVector minimumCurve = algorithm.getMinimumCurve(0,analysis); ASSERT_EQ(6u,minimumCurve.size()); DoubleVector values = minimumCurve[0].objectiveValues(); EXPECT_DOUBLE_EQ(20.0,values[0]); EXPECT_DOUBLE_EQ(20.0,values[1]); values = minimumCurve[1].objectiveValues(); EXPECT_DOUBLE_EQ(18.0,values[0]); EXPECT_DOUBLE_EQ(20.0,values[1]); values = minimumCurve[2].objectiveValues(); EXPECT_DOUBLE_EQ(15.0,values[0]); EXPECT_DOUBLE_EQ(19.0,values[1]); values = minimumCurve[3].objectiveValues(); EXPECT_DOUBLE_EQ(16.0,values[0]); EXPECT_DOUBLE_EQ(16.0,values[1]); values = minimumCurve[4].objectiveValues(); EXPECT_DOUBLE_EQ(17.0,values[0]); EXPECT_DOUBLE_EQ(14.0,values[1]); values = minimumCurve[5].objectiveValues(); EXPECT_DOUBLE_EQ(20.0,values[0]); EXPECT_DOUBLE_EQ(12.0,values[1]); OptimizationDataPointVector paretoFront = algorithm.getParetoFront(analysis); for (const OptimizationDataPoint& paretoPoint : paretoFront) { EXPECT_FALSE(std::find(minimumCurve.begin(),minimumCurve.end(),paretoPoint) == minimumCurve.end()); } ASSERT_EQ(4u,paretoFront.size()); // expect same order as curve0, although different method for calculating values = paretoFront[0].objectiveValues(); EXPECT_DOUBLE_EQ(15.0,values[0]); EXPECT_DOUBLE_EQ(19.0,values[1]); // minimizes f0 values = paretoFront[1].objectiveValues(); EXPECT_DOUBLE_EQ(16.0,values[0]); EXPECT_DOUBLE_EQ(16.0,values[1]); values = paretoFront[2].objectiveValues(); EXPECT_DOUBLE_EQ(17.0,values[0]); EXPECT_DOUBLE_EQ(14.0,values[1]); values = paretoFront[3].objectiveValues(); EXPECT_DOUBLE_EQ(20.0,values[0]); EXPECT_DOUBLE_EQ(12.0,values[1]); // minimizes f1 }