runmanager::WorkItem RubyContinuousVariable_Impl::createWorkItem(
     const QVariant& value,
     const openstudio::path& rubyIncludeDirectory) const
 {
   // This is only complete if this is the only RubyContinuousVariable using this
   // RubyMeasure.
   RubyMeasure pertClone = measure().clone().cast<RubyMeasure>();
   ruleset::OSArgument arg = argument().clone();
   arg.setValue(value.toDouble());
   pertClone.setArgument(arg);
   return pertClone.createWorkItem(rubyIncludeDirectory);
 }
 bool RubyContinuousVariable_Impl::setRubyMeasure(const RubyMeasure& measure) {
   if (!fileTypesAreCompatible(m_measure,
                               measure.inputFileType(),
                               measure.outputFileType()))
   {
     return false;
   }
   disconnectChild(m_measure);
   m_measure = measure;
   connectChild(m_measure,true);
   onChange(AnalysisObject_Impl::InvalidatesResults);
   return true;
 }
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(ProjectFixture, RubyMeasureRecord_BCLMeasure) {
    // Construct problem with RubyMeasure that points to BCLMeasure
    Problem problem("Problem",VariableVector(),runmanager::Workflow());
    MeasureGroup dvar("Variable",MeasureVector());
    problem.push(dvar);
    openstudio::path measuresPath = resourcesPath() / toPath("/utilities/BCL/Measures");
    openstudio::path dir = measuresPath / toPath("SetWindowToWallRatioByFacade");
    BCLMeasure measure = BCLMeasure::load(dir).get();
    RubyMeasure rpert(measure);
    dvar.push(rpert);
    OSArgument arg = OSArgument::makeDoubleArgument("wwr");
    arg.setValue(0.4);
    rpert.setArgument(arg);
    arg = OSArgument::makeIntegerArgument("typo_arg");
    arg.setDefaultValue(1);
    rpert.setArgument(arg);

    // Serialize to database
    {
        ProjectDatabase database = getCleanDatabase("RubyMeasureRecord_BCLMeasure");

        bool didStartTransaction = database.startTransaction();
        EXPECT_TRUE(didStartTransaction);

        // Problem Record
        ProblemRecord problemRecord = ProblemRecord::factoryFromProblem(problem,database);

        database.save();
        if (didStartTransaction) {
            EXPECT_TRUE(database.commitTransaction());
        }
    }

    // Re-open database, de-serialize, verify that RubyMeasure is intact.
    openstudio::path tempDir1 = measuresPath / toPath(toString(createUUID()));
    {
        ProjectDatabase database = getExistingDatabase("RubyMeasureRecord_BCLMeasure");
        ASSERT_EQ(1u,ProblemRecord::getProblemRecords(database).size());
        ASSERT_EQ(1u,MeasureGroupRecord::getMeasureGroupRecords(database).size());
        EXPECT_EQ(1u,RubyMeasureRecord::getRubyMeasureRecords(database).size());

        MeasureRecordVector dprs = MeasureGroupRecord::getMeasureGroupRecords(database)[0].measureRecords(false);
        ASSERT_EQ(1u,dprs.size());
        ASSERT_TRUE(dprs[0].optionalCast<RubyMeasureRecord>());
        RubyMeasureRecord rpr = dprs[0].cast<RubyMeasureRecord>();
        RubyMeasure rp = rpr.rubyMeasure();
        EXPECT_TRUE(rp.usesBCLMeasure());
        EXPECT_TRUE(rp.measure());
        EXPECT_EQ(dir,rp.measureDirectory());
        EXPECT_EQ(measure.uuid(),rp.measureUUID());
        EXPECT_EQ(measure.versionUUID(),rp.measureVersionUUID());
        EXPECT_ANY_THROW(rp.perturbationScript());
        EXPECT_EQ(2u,rp.arguments().size());
        EXPECT_FALSE(rp.hasIncompleteArguments());

        // Update measure and save
        BCLMeasure newVersion = measure.clone(tempDir1).get();
        newVersion.setDescription("Window to wall ratio with sill height configurable.");
        newVersion.save();
        EXPECT_NE(measure.versionUUID(),newVersion.versionUUID());
        OSArgumentVector args;
        args.push_back(OSArgument::makeDoubleArgument("wwr"));
        args.push_back(OSArgument::makeDoubleArgument("sillHeight"));

        Problem problemCopy = ProblemRecord::getProblemRecords(database)[0].problem();
        problemCopy.updateMeasure(newVersion,args,false);

        bool didStartTransaction = database.startTransaction();
        EXPECT_TRUE(didStartTransaction);

        // Problem Record
        ProblemRecord problemRecord = ProblemRecord::factoryFromProblem(problemCopy,database);

        database.save();
        if (didStartTransaction) {
            EXPECT_TRUE(database.commitTransaction());
        }
    }

    // Re-open database, check that old argument records are gone, check that de-serialized object ok
    openstudio::path tempDir2 = measuresPath / toPath(toString(createUUID()));
    {
        ProjectDatabase database = getExistingDatabase("RubyMeasureRecord_BCLMeasure");
        ASSERT_EQ(1u,ProblemRecord::getProblemRecords(database).size());
        EXPECT_EQ(1u,MeasureGroupRecord::getMeasureGroupRecords(database).size());
        EXPECT_EQ(1u,RubyMeasureRecord::getRubyMeasureRecords(database).size());
        EXPECT_EQ(1u,FileReferenceRecord::getFileReferenceRecords(database).size());
        EXPECT_EQ(2u,OSArgumentRecord::getOSArgumentRecords(database).size());

        Problem problemCopy = ProblemRecord::getProblemRecords(database)[0].problem();
        InputVariableVector vars = problemCopy.variables();
        ASSERT_FALSE(vars.empty());
        ASSERT_TRUE(vars[0].optionalCast<MeasureGroup>());
        MeasureVector dps = vars[0].cast<MeasureGroup>().measures(false);
        ASSERT_FALSE(dps.empty());
        ASSERT_TRUE(dps[0].optionalCast<RubyMeasure>());
        RubyMeasure rp = dps[0].cast<RubyMeasure>();
        EXPECT_TRUE(rp.usesBCLMeasure());
        EXPECT_TRUE(rp.measure());
        EXPECT_EQ(tempDir1,rp.measureDirectory());
        EXPECT_EQ(measure.uuid(),rp.measureUUID());
        EXPECT_NE(measure.versionUUID(),rp.measureVersionUUID());
        EXPECT_ANY_THROW(rp.perturbationScript());
        ASSERT_EQ(2u,rp.arguments().size());
        EXPECT_TRUE(rp.hasIncompleteArguments());
        EXPECT_EQ("wwr",rp.arguments()[0].name());
        ASSERT_EQ(1u,rp.incompleteArguments().size());
        EXPECT_EQ("sillHeight",rp.incompleteArguments()[0].name());

        // Set to different measure
        BCLMeasure measure2 = measure.clone(tempDir2).get();
        measure2.changeUID();
        measure2.incrementVersionId();
        measure2.save();
        measure2 = BCLMeasure::load(tempDir2).get();
        EXPECT_NE(measure.uuid(),measure2.uuid());
        EXPECT_NE(measure.versionUUID(),measure2.versionUUID());
        rp.setMeasure(measure2);
        EXPECT_TRUE(rp.isDirty());
        EXPECT_TRUE(problemCopy.isDirty());

        bool didStartTransaction = database.startTransaction();
        EXPECT_TRUE(didStartTransaction);

        // Problem Record
        ProblemRecord problemRecord = ProblemRecord::factoryFromProblem(problemCopy,database);

        database.save();
        if (didStartTransaction) {
            EXPECT_TRUE(database.commitTransaction());
        }
    }

    // Re-open database, check that old measure and all argument records are gone
    {
        ProjectDatabase database = getExistingDatabase("RubyMeasureRecord_BCLMeasure");
        ASSERT_EQ(1u,ProblemRecord::getProblemRecords(database).size());
        EXPECT_EQ(1u,MeasureGroupRecord::getMeasureGroupRecords(database).size());
        EXPECT_EQ(1u,RubyMeasureRecord::getRubyMeasureRecords(database).size());
        EXPECT_EQ(1u,FileReferenceRecord::getFileReferenceRecords(database).size());
        EXPECT_EQ(0u,OSArgumentRecord::getOSArgumentRecords(database).size());

        Problem problemCopy = ProblemRecord::getProblemRecords(database)[0].problem();
        InputVariableVector vars = problemCopy.variables();
        ASSERT_FALSE(vars.empty());
        ASSERT_TRUE(vars[0].optionalCast<MeasureGroup>());
        MeasureVector dps = vars[0].cast<MeasureGroup>().measures(false);
        ASSERT_FALSE(dps.empty());
        ASSERT_TRUE(dps[0].optionalCast<RubyMeasure>());
        RubyMeasure rp = dps[0].cast<RubyMeasure>();
        EXPECT_TRUE(rp.usesBCLMeasure());
        EXPECT_TRUE(rp.measure());
        EXPECT_EQ(tempDir2,rp.measureDirectory());
        EXPECT_NE(measure.uuid(),rp.measureUUID());
        EXPECT_NE(measure.versionUUID(),rp.measureVersionUUID());
        EXPECT_ANY_THROW(rp.perturbationScript());
        ASSERT_EQ(0u,rp.arguments().size());
        EXPECT_FALSE(rp.hasIncompleteArguments());
    }

    boost::filesystem::remove_all(tempDir1);
    boost::filesystem::remove_all(tempDir2);
}
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;
}