LCOV - code coverage report
Current view: top level - EnergyPlus - ResultsFramework.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 654 889 73.6 %
Date: 2023-01-17 19:17:23 Functions: 67 87 77.0 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // C++ Headers
      49             : #include <algorithm>
      50             : #include <cassert>
      51             : #include <cmath>
      52             : #include <map>
      53             : #include <ostream>
      54             : #include <string>
      55             : #include <vector>
      56             : 
      57             : #include <fmt/format.h>
      58             : #include <milo/dtoa.h>
      59             : 
      60             : // ObjexxFCL Headers
      61             : #include <ObjexxFCL/Array.functions.hh>
      62             : #include <ObjexxFCL/Array1D.hh>
      63             : #include <ObjexxFCL/Reference.fwd.hh>
      64             : #include <ObjexxFCL/string.functions.hh>
      65             : 
      66             : // EnergyPlus Headers
      67             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      68             : #include <EnergyPlus/DataStringGlobals.hh>
      69             : #include <EnergyPlus/GlobalNames.hh>
      70             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      71             : #include <EnergyPlus/ResultsFramework.hh>
      72             : #include <EnergyPlus/UtilityRoutines.hh>
      73             : 
      74             : namespace EnergyPlus {
      75             : 
      76             : namespace ResultsFramework {
      77             : 
      78             :     using namespace OutputProcessor;
      79             :     using OutputProcessor::RealVariables;
      80             :     using OutputProcessor::RealVariableType;
      81             : 
      82             :     // trim string
      83       39925 :     std::string trim(std::string_view const s)
      84             :     {
      85       39925 :         if (s.empty()) {
      86        2645 :             return std::string{};
      87             :         }
      88       37280 :         auto const first = s.find_first_not_of(' ');
      89       37280 :         auto const last = s.find_last_not_of(' ');
      90       37280 :         if ((first == std::string::npos) || (last == std::string::npos)) {
      91           0 :             return std::string{};
      92             :         } else {
      93       37280 :             return std::string{s.substr(first, last - first + 1)};
      94             :         }
      95             :     }
      96             : 
      97             :     // Class SimInfo
      98         771 :     void SimInfo::setProgramVersion(const std::string &programVersion)
      99             :     {
     100         771 :         ProgramVersion = programVersion;
     101         771 :     }
     102             : 
     103           0 :     std::string SimInfo::getProgramVersion() const
     104             :     {
     105           0 :         return ProgramVersion;
     106             :     }
     107             : 
     108           0 :     void SimInfo::setSimulationEnvironment(const std::string &simulationEnvironment)
     109             :     {
     110           0 :         SimulationEnvironment = simulationEnvironment;
     111           0 :     }
     112             : 
     113           0 :     void SimInfo::setInputModelURI(const std::string &inputModelURI)
     114             :     {
     115           0 :         InputModelURI = inputModelURI;
     116           0 :     }
     117             : 
     118         771 :     void SimInfo::setStartDateTimeStamp(const std::string &startDateTimeStamp)
     119             :     {
     120         771 :         StartDateTimeStamp = startDateTimeStamp;
     121         771 :     }
     122             : 
     123         771 :     void SimInfo::setRunTime(const std::string &elapsedTime)
     124             :     {
     125         771 :         RunTime = elapsedTime;
     126         771 :     }
     127             : 
     128         771 :     void SimInfo::setNumErrorsWarmup(const std::string &numWarningsDuringWarmup, const std::string &numSevereDuringWarmup)
     129             :     {
     130         771 :         NumWarningsDuringWarmup = numWarningsDuringWarmup;
     131         771 :         NumSevereDuringWarmup = numSevereDuringWarmup;
     132         771 :     }
     133             : 
     134         771 :     void SimInfo::setNumErrorsSizing(const std::string &numWarningsDuringSizing, const std::string &numSevereDuringSizing)
     135             :     {
     136         771 :         NumWarningsDuringSizing = numWarningsDuringSizing;
     137         771 :         NumSevereDuringSizing = numSevereDuringSizing;
     138         771 :     }
     139             : 
     140         771 :     void SimInfo::setNumErrorsSummary(const std::string &numWarnings, const std::string &numSevere)
     141             :     {
     142         771 :         NumWarnings = numWarnings;
     143         771 :         NumSevere = numSevere;
     144         771 :     }
     145             : 
     146           2 :     json SimInfo::getJSON() const
     147             :     {
     148             :         json root = {{"ProgramVersion", ProgramVersion},
     149             :                      {"SimulationEnvironment", SimulationEnvironment},
     150             :                      {"InputModelURI", InputModelURI},
     151             :                      {"StartDateTimeStamp", StartDateTimeStamp},
     152             :                      {"RunTime", RunTime},
     153             :                      {"ErrorSummary", {{"NumWarnings", NumWarnings}, {"NumSevere", NumSevere}}},
     154             :                      {"ErrorSummaryWarmup", {{"NumWarnings", NumWarningsDuringWarmup}, {"NumSevere", NumSevereDuringWarmup}}},
     155           2 :                      {"ErrorSummarySizing", {{"NumWarnings", NumWarningsDuringSizing}, {"NumSevere", NumSevereDuringSizing}}}};
     156           2 :         return root;
     157             :     }
     158             : 
     159             :     // Class Variable
     160        8137 :     Variable::Variable(const std::string &VarName,
     161             :                        const OutputProcessor::ReportingFrequency reportFrequency,
     162             :                        const OutputProcessor::TimeStepType timeStepType,
     163             :                        const int ReportID,
     164        8137 :                        const OutputProcessor::Unit units)
     165        8137 :         : varName(VarName), m_timeStepType(timeStepType), rptID(ReportID), Units(units)
     166             :     {
     167        8137 :         setReportFrequency(reportFrequency);
     168        8137 :     }
     169             : 
     170           5 :     Variable::Variable(const std::string &VarName,
     171             :                        const OutputProcessor::ReportingFrequency reportFrequency,
     172             :                        const OutputProcessor::TimeStepType timeStepType,
     173             :                        const int ReportID,
     174             :                        const OutputProcessor::Unit units,
     175           5 :                        const std::string &customUnits)
     176           5 :         : varName(VarName), m_timeStepType(timeStepType), rptID(ReportID), Units(units), m_customUnits(customUnits)
     177             :     {
     178           5 :         setReportFrequency(reportFrequency);
     179           5 :     }
     180             : 
     181         497 :     std::string Variable::variableName() const
     182             :     {
     183         497 :         return varName;
     184             :     }
     185             : 
     186           0 :     void Variable::setVariableName(const std::string &VarName)
     187             :     {
     188           0 :         varName = VarName;
     189           0 :     }
     190             : 
     191           0 :     std::string Variable::sReportFrequency() const
     192             :     {
     193           0 :         return sReportFreq;
     194             :     }
     195             : 
     196           0 :     OutputProcessor::ReportingFrequency Variable::iReportFrequency() const
     197             :     {
     198           0 :         return iReportFreq;
     199             :     }
     200             : 
     201        8142 :     void Variable::setReportFrequency(const OutputProcessor::ReportingFrequency reportFrequency)
     202             :     {
     203        8142 :         iReportFreq = reportFrequency;
     204        8142 :         switch (iReportFreq) {
     205          58 :         case OutputProcessor::ReportingFrequency::EachCall: // each time UpdatedataandReport is called
     206          58 :             if (m_timeStepType == OutputProcessor::TimeStepType::Zone) sReportFreq = "Detailed - Zone";
     207          58 :             if (m_timeStepType == OutputProcessor::TimeStepType::System) sReportFreq = "Detailed - HVAC";
     208          58 :             break;
     209          50 :         case OutputProcessor::ReportingFrequency::TimeStep: // at 'EndTimeStepFlag'
     210          50 :             sReportFreq = "TimeStep";
     211          50 :             break;
     212        1049 :         case OutputProcessor::ReportingFrequency::Hourly: // at 'EndHourFlag'
     213        1049 :             sReportFreq = "Hourly";
     214        1049 :             break;
     215          71 :         case OutputProcessor::ReportingFrequency::Daily: // at 'EndDayFlag'
     216          71 :             sReportFreq = "Daily";
     217          71 :             break;
     218        4090 :         case OutputProcessor::ReportingFrequency::Monthly: // at end of month
     219        4090 :             sReportFreq = "Monthly";
     220        4090 :             break;
     221        2824 :         case OutputProcessor::ReportingFrequency::Simulation: // once per environment 'EndEnvrnFlag'
     222        2824 :             sReportFreq = "RunPeriod";
     223        2824 :             break;
     224           0 :         case OutputProcessor::ReportingFrequency::Yearly: // once per environment 'EndEnvrnFlag'
     225           0 :             sReportFreq = "Yearly";
     226           0 :             break;
     227           0 :         default:
     228           0 :             assert(false);
     229             :         }
     230        8142 :     }
     231             : 
     232           0 :     OutputProcessor::TimeStepType Variable::timeStepType() const
     233             :     {
     234           0 :         return m_timeStepType;
     235             :     }
     236             : 
     237           0 :     void Variable::setTimeStepType(const OutputProcessor::TimeStepType timeStepType)
     238             :     {
     239           0 :         m_timeStepType = timeStepType;
     240           0 :     }
     241             : 
     242        8113 :     int Variable::reportID() const
     243             :     {
     244        8113 :         return rptID;
     245             :     }
     246             : 
     247           0 :     void Variable::setReportID(int Id)
     248             :     {
     249           0 :         rptID = Id;
     250           0 :     }
     251             : 
     252         494 :     OutputProcessor::Unit Variable::units() const
     253             :     {
     254         494 :         return Units;
     255             :     }
     256             : 
     257           0 :     void Variable::setUnits(const OutputProcessor::Unit units)
     258             :     {
     259           0 :         Units = units;
     260           0 :     }
     261             : 
     262         382 :     std::string Variable::customUnits() const
     263             :     {
     264         382 :         return m_customUnits;
     265             :     }
     266             : 
     267           0 :     void Variable::setCustomUnits(const std::string &customUnits)
     268             :     {
     269           0 :         m_customUnits = customUnits;
     270           0 :     }
     271             : 
     272      105975 :     void Variable::pushValue(const double val)
     273             :     {
     274      105975 :         Values.push_back(val);
     275      105975 :     }
     276             : 
     277       25733 :     double Variable::value(size_t index) const
     278             :     {
     279       25733 :         return Values.at(index);
     280             :     }
     281             : 
     282       26825 :     size_t Variable::numValues() const
     283             :     {
     284       26825 :         return Values.size();
     285             :     }
     286             : 
     287          96 :     json Variable::getJSON() const
     288             :     {
     289          96 :         json root;
     290          96 :         if (m_customUnits.empty()) {
     291          96 :             root = {{"Name", varName}, {"Units", unitEnumToString(Units)}, {"Frequency", sReportFreq}};
     292             :         } else {
     293           0 :             root = {{"Name", varName}, {"Units", m_customUnits}, {"Frequency", sReportFreq}};
     294             :         }
     295          96 :         return root;
     296             :     }
     297             : 
     298             :     // Class OutputVariable
     299          30 :     OutputVariable::OutputVariable(const std::string &VarName,
     300             :                                    const OutputProcessor::ReportingFrequency reportFrequency,
     301             :                                    const OutputProcessor::TimeStepType timeStepType,
     302             :                                    const int ReportID,
     303          30 :                                    const OutputProcessor::Unit units)
     304          30 :         : Variable(VarName, reportFrequency, timeStepType, ReportID, units)
     305             :     {
     306          30 :     }
     307             : 
     308           0 :     OutputVariable::OutputVariable(const std::string &VarName,
     309             :                                    const OutputProcessor::ReportingFrequency reportFrequency,
     310             :                                    const OutputProcessor::TimeStepType timeStepType,
     311             :                                    const int ReportID,
     312             :                                    const OutputProcessor::Unit units,
     313           0 :                                    const std::string &customUnits)
     314           0 :         : Variable(VarName, reportFrequency, timeStepType, ReportID, units, customUnits)
     315             :     {
     316           0 :     }
     317             : 
     318             :     // Class MeterVariable
     319        7734 :     MeterVariable::MeterVariable(const std::string &VarName,
     320             :                                  const OutputProcessor::ReportingFrequency reportFrequency,
     321             :                                  const int ReportID,
     322             :                                  const OutputProcessor::Unit units,
     323             :                                  const bool MeterOnly,
     324        7734 :                                  const bool Accumulative)
     325        7734 :         : Variable(VarName, reportFrequency, OutputProcessor::TimeStepType::Zone, ReportID, units)
     326             :     {
     327        7734 :         acc = Accumulative;
     328        7734 :         meter_only = MeterOnly;
     329        7734 :     }
     330             : 
     331           0 :     bool MeterVariable::accumulative() const
     332             :     {
     333           0 :         return acc;
     334             :     }
     335             : 
     336           0 :     void MeterVariable::setAccumulative(bool state)
     337             :     {
     338           0 :         acc = state;
     339           0 :     }
     340             : 
     341         518 :     bool MeterVariable::meterOnly() const
     342             :     {
     343         518 :         return meter_only;
     344             :     }
     345             : 
     346           0 :     void MeterVariable::setMeterOnly(bool state)
     347             :     {
     348           0 :         meter_only = state;
     349           0 :     }
     350             : 
     351           0 :     json MeterVariable::getJSON() const
     352             :     {
     353           0 :         json root = Variable::getJSON();
     354           0 :         if (acc) {
     355           0 :             root["Cumulative"] = true;
     356             :         }
     357             :         //        if (meter_only) {
     358             :         //            root["MeterOnly"] = true;
     359             :         //        }
     360           0 :         return root;
     361             :     }
     362             : 
     363             :     // class DataFrame
     364       10794 :     DataFrame::DataFrame(const std::string &ReportFreq)
     365             :     {
     366       10794 :         ReportFrequency = ReportFreq;
     367       10794 :     }
     368             : 
     369         379 :     void DataFrame::addVariable(Variable const &var)
     370             :     {
     371         379 :         lastVarID = var.reportID();
     372         379 :         variableMap.emplace(lastVarID, var);
     373         379 :     }
     374             : 
     375           0 :     Variable &DataFrame::lastVariable()
     376             :     {
     377           0 :         return variableMap.at(lastVarID);
     378             :     }
     379             : 
     380       22061 :     void DataFrame::newRow(const int month, const int dayOfMonth, int hourOfDay, int curMin)
     381             :     {
     382       22061 :         if (curMin > 0) {
     383       11340 :             hourOfDay -= 1;
     384             :         }
     385       22061 :         if (curMin == 60) {
     386        1584 :             curMin = 0;
     387        1584 :             hourOfDay += 1;
     388             :         }
     389             : 
     390             :         // future start of ISO 8601 datetime output
     391             :         // fmt::format("YYYY-{:02d}/{:02d}T{:02d}:{:02d}:00", month, dayOfMonth, hourOfDay, curMin);
     392       44122 :         TS.emplace_back(fmt::format("{:02d}/{:02d} {:02d}:{:02d}:00", month, dayOfMonth, hourOfDay, curMin));
     393       22061 :     }
     394             : 
     395             :     //    void DataFrame::newRow(const std::string &ts)
     396             :     //    {
     397             :     //        TS.emplace_back(ts);
     398             :     //    }
     399             : 
     400        8086 :     void DataFrame::setRDataFrameEnabled(bool state)
     401             :     {
     402        8086 :         RDataFrameEnabled = state;
     403        8086 :     }
     404             : 
     405          27 :     void DataFrame::setIDataFrameEnabled(bool state)
     406             :     {
     407          27 :         IDataFrameEnabled = state;
     408          27 :     }
     409             : 
     410      372901 :     bool DataFrame::rDataFrameEnabled() const
     411             :     {
     412      372901 :         return RDataFrameEnabled;
     413             :     }
     414             : 
     415          78 :     bool DataFrame::iDataFrameEnabled() const
     416             :     {
     417          78 :         return IDataFrameEnabled;
     418             :     }
     419      345784 :     void DataFrame::setRVariablesScanned(bool state)
     420             :     {
     421      345784 :         RVariablesScanned = state;
     422      345784 :     }
     423             : 
     424          49 :     void DataFrame::setIVariablesScanned(bool state)
     425             :     {
     426          49 :         IVariablesScanned = state;
     427          49 :     }
     428             : 
     429       11873 :     bool DataFrame::rVariablesScanned() const
     430             :     {
     431       11873 :         return RVariablesScanned;
     432             :     }
     433             : 
     434        6150 :     bool DataFrame::iVariablesScanned() const
     435             :     {
     436        6150 :         return IVariablesScanned;
     437             :     }
     438             : 
     439       24255 :     void DataFrame::pushVariableValue(const int reportID, double value)
     440             :     {
     441       24255 :         variableMap[reportID].pushValue(value);
     442       24255 :     }
     443             : 
     444           7 :     json DataFrame::getVariablesJSON()
     445             :     {
     446           7 :         json arr = json::array();
     447         103 :         for (auto const &varMap : variableMap) {
     448          96 :             arr.push_back(varMap.second.getJSON());
     449             :         }
     450           7 :         return arr;
     451             :     }
     452             : 
     453          12 :     json DataFrame::getJSON() const
     454             :     {
     455          12 :         json root;
     456          24 :         json cols = json::array();
     457          24 :         json rows = json::array();
     458             : 
     459         391 :         for (auto const &varMap : variableMap) {
     460         379 :             if (varMap.second.customUnits().empty()) {
     461         376 :                 cols.push_back({{"Variable", varMap.second.variableName()}, {"Units", unitEnumToString(varMap.second.units())}});
     462             :             } else {
     463           3 :                 cols.push_back({{"Variable", varMap.second.variableName()}, {"Units", varMap.second.customUnits()}});
     464             :             }
     465             :         }
     466             : 
     467          24 :         json vals = json::array();
     468             : 
     469        2627 :         for (size_t row = 0; row < TS.size(); ++row) {
     470        2615 :             vals.clear();
     471             : 
     472       27962 :             for (auto const &varMap : variableMap) {
     473       25347 :                 if (row < varMap.second.numValues()) {
     474       24255 :                     vals.push_back(varMap.second.value(row));
     475             :                 } else {
     476        1092 :                     vals.push_back(nullptr);
     477             :                 }
     478             :             }
     479        2615 :             rows.push_back({{TS.at(row), vals}});
     480             :         }
     481          12 :         root = {{"ReportFrequency", ReportFrequency}, {"Cols", cols}, {"Rows", rows}};
     482          24 :         return root;
     483             :     }
     484             : 
     485        7734 :     void MeterDataFrame::addVariable(MeterVariable const &var)
     486             :     {
     487        7734 :         lastVarID = var.reportID();
     488        7734 :         meterMap.emplace(lastVarID, var);
     489        7734 :     }
     490             : 
     491       81720 :     void MeterDataFrame::pushVariableValue(const int reportID, double value)
     492             :     {
     493       81720 :         meterMap[reportID].pushValue(value);
     494       81720 :     }
     495             : 
     496          16 :     json MeterDataFrame::getJSON(bool meterOnlyCheck) const
     497             :     {
     498          16 :         json root;
     499          32 :         json cols = json::array();
     500          32 :         json rows = json::array();
     501             : 
     502         154 :         for (auto const &varMap : meterMap) {
     503         138 :             if (!(meterOnlyCheck && varMap.second.meterOnly())) {
     504         118 :                 cols.push_back({{"Variable", varMap.second.variableName()}, {"Units", unitEnumToString(varMap.second.units())}});
     505             :             }
     506             :         }
     507             : 
     508          16 :         if (cols.empty()) return root;
     509             : 
     510          24 :         json vals = json::array();
     511             : 
     512         174 :         for (size_t row = 0; row < TS.size(); ++row) {
     513         162 :             vals.clear();
     514             : 
     515        1640 :             for (auto const &varMap : meterMap) {
     516        1478 :                 if (!(meterOnlyCheck && varMap.second.meterOnly())) {
     517        1478 :                     if (row < varMap.second.numValues()) {
     518        1478 :                         vals.push_back(varMap.second.value(row));
     519             :                     } else {
     520           0 :                         vals.push_back(nullptr);
     521             :                     }
     522             :                 }
     523             :             }
     524         162 :             rows.push_back({{TS.at(row), vals}});
     525             :         }
     526          12 :         root = {{"ReportFrequency", ReportFrequency}, {"Cols", cols}, {"Rows", rows}};
     527          12 :         return root;
     528             :     }
     529             : 
     530           4 :     void DataFrame::writeReport(JsonOutputFilePaths &jsonOutputFilePaths, bool outputJSON, bool outputCBOR, bool outputMsgPack)
     531             :     {
     532             : 
     533           8 :         json root = getJSON();
     534           4 :         if (ReportFrequency == "Detailed-HVAC") {
     535           1 :             if (outputJSON) {
     536           1 :                 FileSystem::writeFile<FileSystem::FileTypes::JSON>(jsonOutputFilePaths.outputTSHvacJsonFilePath, root);
     537             :             }
     538           1 :             if (outputCBOR) {
     539           1 :                 FileSystem::writeFile<FileSystem::FileTypes::CBOR>(jsonOutputFilePaths.outputTSHvacCborFilePath, root);
     540             :             }
     541           1 :             if (outputMsgPack) {
     542           1 :                 FileSystem::writeFile<FileSystem::FileTypes::MsgPack>(jsonOutputFilePaths.outputTSHvacMsgPackFilePath, root);
     543             :             }
     544           3 :         } else if (ReportFrequency == "Detailed-Zone") {
     545           0 :             if (outputJSON) {
     546           0 :                 FileSystem::writeFile<FileSystem::FileTypes::JSON>(jsonOutputFilePaths.outputTSZoneJsonFilePath, root);
     547             :             }
     548           0 :             if (outputCBOR) {
     549           0 :                 FileSystem::writeFile<FileSystem::FileTypes::CBOR>(jsonOutputFilePaths.outputTSZoneCborFilePath, root);
     550             :             }
     551           0 :             if (outputMsgPack) {
     552           0 :                 FileSystem::writeFile<FileSystem::FileTypes::MsgPack>(jsonOutputFilePaths.outputTSZoneMsgPackFilePath, root);
     553             :             }
     554           3 :         } else if (ReportFrequency == "TimeStep") {
     555           0 :             if (outputJSON) {
     556           0 :                 FileSystem::writeFile<FileSystem::FileTypes::JSON>(jsonOutputFilePaths.outputTSJsonFilePath, root);
     557             :             }
     558           0 :             if (outputCBOR) {
     559           0 :                 FileSystem::writeFile<FileSystem::FileTypes::CBOR>(jsonOutputFilePaths.outputTSCborFilePath, root);
     560             :             }
     561           0 :             if (outputMsgPack) {
     562           0 :                 FileSystem::writeFile<FileSystem::FileTypes::MsgPack>(jsonOutputFilePaths.outputTSMsgPackFilePath, root);
     563             :             }
     564           3 :         } else if (ReportFrequency == "Daily") {
     565           0 :             if (outputJSON) {
     566           0 :                 FileSystem::writeFile<FileSystem::FileTypes::JSON>(jsonOutputFilePaths.outputDYJsonFilePath, root);
     567             :             }
     568           0 :             if (outputCBOR) {
     569           0 :                 FileSystem::writeFile<FileSystem::FileTypes::CBOR>(jsonOutputFilePaths.outputDYCborFilePath, root);
     570             :             }
     571           0 :             if (outputMsgPack) {
     572           0 :                 FileSystem::writeFile<FileSystem::FileTypes::MsgPack>(jsonOutputFilePaths.outputDYMsgPackFilePath, root);
     573             :             }
     574           3 :         } else if (ReportFrequency == "Hourly") {
     575           3 :             if (outputJSON) {
     576           3 :                 FileSystem::writeFile<FileSystem::FileTypes::JSON>(jsonOutputFilePaths.outputHRJsonFilePath, root);
     577             :             }
     578           3 :             if (outputCBOR) {
     579           1 :                 FileSystem::writeFile<FileSystem::FileTypes::CBOR>(jsonOutputFilePaths.outputHRCborFilePath, root);
     580             :             }
     581           3 :             if (outputMsgPack) {
     582           1 :                 FileSystem::writeFile<FileSystem::FileTypes::MsgPack>(jsonOutputFilePaths.outputHRMsgPackFilePath, root);
     583             :             }
     584           0 :         } else if (ReportFrequency == "Monthly") {
     585           0 :             if (outputJSON) {
     586           0 :                 FileSystem::writeFile<FileSystem::FileTypes::JSON>(jsonOutputFilePaths.outputMNJsonFilePath, root);
     587             :             }
     588           0 :             if (outputCBOR) {
     589           0 :                 FileSystem::writeFile<FileSystem::FileTypes::CBOR>(jsonOutputFilePaths.outputMNCborFilePath, root);
     590             :             }
     591           0 :             if (outputMsgPack) {
     592           0 :                 FileSystem::writeFile<FileSystem::FileTypes::MsgPack>(jsonOutputFilePaths.outputMNMsgPackFilePath, root);
     593             :             }
     594           0 :         } else if (ReportFrequency == "RunPeriod") {
     595           0 :             if (outputJSON) {
     596           0 :                 FileSystem::writeFile<FileSystem::FileTypes::JSON>(jsonOutputFilePaths.outputSMJsonFilePath, root);
     597             :             }
     598           0 :             if (outputCBOR) {
     599           0 :                 FileSystem::writeFile<FileSystem::FileTypes::CBOR>(jsonOutputFilePaths.outputSMCborFilePath, root);
     600             :             }
     601           0 :             if (outputMsgPack) {
     602           0 :                 FileSystem::writeFile<FileSystem::FileTypes::MsgPack>(jsonOutputFilePaths.outputSMMsgPackFilePath, root);
     603             :             }
     604           0 :         } else if (ReportFrequency == "Yearly") {
     605           0 :             if (outputJSON) {
     606           0 :                 FileSystem::writeFile<FileSystem::FileTypes::JSON>(jsonOutputFilePaths.outputYRJsonFilePath, root);
     607             :             }
     608           0 :             if (outputCBOR) {
     609           0 :                 FileSystem::writeFile<FileSystem::FileTypes::CBOR>(jsonOutputFilePaths.outputYRCborFilePath, root);
     610             :             }
     611           0 :             if (outputMsgPack) {
     612           0 :                 FileSystem::writeFile<FileSystem::FileTypes::MsgPack>(jsonOutputFilePaths.outputYRMsgPackFilePath, root);
     613             :             }
     614             :         }
     615           4 :     }
     616             :     // class Table
     617             : 
     618         676 :     Table::Table(Array2D_string const &body,
     619             :                  Array1D_string const &rowLabels,
     620             :                  Array1D_string const &columnLabels,
     621             :                  std::string const &tableName,
     622         676 :                  std::string const &footnoteText)
     623             :     {
     624             : 
     625         676 :         size_t sizeColumnLabels = columnLabels.size();
     626         676 :         size_t sizeRowLabels = rowLabels.size();
     627         676 :         TableName = tableName;
     628         676 :         FootnoteText = footnoteText;
     629             : 
     630        5562 :         for (size_t iCol = 0, k = body.index(1, 1); iCol < sizeColumnLabels; ++iCol) {
     631        4886 :             ColHeaders.push_back(columnLabels[iCol]);
     632        9772 :             std::vector<std::string> col;
     633       44811 :             for (size_t iRow = 0; iRow < sizeRowLabels; ++iRow) {
     634       39925 :                 if (iCol == 0) {
     635             :                     // do this once only
     636        4431 :                     RowHeaders.push_back(rowLabels[iRow]);
     637             :                 }
     638       39925 :                 col.push_back(trim(body[k]));
     639       39925 :                 ++k;
     640             :             }
     641        4886 :             Data.push_back(col);
     642             :         }
     643         676 :     }
     644             : 
     645         260 :     json Table::getJSON() const
     646             :     {
     647         260 :         json root;
     648         520 :         json cols = json::array();
     649         520 :         json rows;
     650             : 
     651        2091 :         for (size_t col = 0; col < ColHeaders.size(); ++col) {
     652        1831 :             cols.push_back(ColHeaders[col]);
     653             :         }
     654             : 
     655        1917 :         for (size_t row = 0; row < RowHeaders.size(); ++row) {
     656        3314 :             json rowvec = json::array();
     657       14833 :             for (size_t col = 0; col < ColHeaders.size(); ++col) {
     658       13176 :                 rowvec.push_back(Data[col][row]);
     659             :             }
     660        1657 :             rows[RowHeaders[row]] = rowvec;
     661             :         }
     662             : 
     663         260 :         root = {{"TableName", TableName}, {"Cols", cols}, {"Rows", rows}};
     664             : 
     665         260 :         if (!FootnoteText.empty()) root["Footnote"] = FootnoteText;
     666         520 :         return root;
     667             :     }
     668             : 
     669             :     // class Report
     670             : 
     671          35 :     json Report::getJSON() const
     672             :     {
     673             : 
     674          35 :         json root = {{"ReportName", ReportName}, {"For", ReportForString}};
     675             : 
     676          70 :         json cols = json::array();
     677             : 
     678         295 :         for (auto const &table : Tables) {
     679         260 :             cols.push_back(table.getJSON());
     680             :         }
     681             : 
     682          35 :         root["Tables"] = cols;
     683          70 :         return root;
     684             :     }
     685             : 
     686             :     // class ReportsCollection
     687         771 :     ReportsCollection::ReportsCollection()
     688             :     {
     689         771 :     }
     690             : 
     691         620 :     void ReportsCollection::addReportTable(Array2D_string const &body,
     692             :                                            Array1D_string const &rowLabels,
     693             :                                            Array1D_string const &columnLabels,
     694             :                                            std::string const &reportName,
     695             :                                            std::string const &reportForString,
     696             :                                            std::string const &tableName)
     697             :     {
     698         620 :         addReportTable(body, rowLabels, columnLabels, reportName, reportForString, tableName, "");
     699         620 :     }
     700             : 
     701         676 :     void ReportsCollection::addReportTable(Array2D_string const &body,
     702             :                                            Array1D_string const &rowLabels,
     703             :                                            Array1D_string const &columnLabels,
     704             :                                            std::string const &reportName,
     705             :                                            std::string const &reportForString,
     706             :                                            std::string const &tableName,
     707             :                                            std::string const &footnoteText)
     708             :     {
     709        1352 :         std::string const key = reportName + reportForString;
     710             :         // Report *r;
     711        1352 :         Table tbl(body, rowLabels, columnLabels, tableName, footnoteText);
     712             : 
     713        1352 :         auto search = reportsMap.find(key);
     714         676 :         if (search != reportsMap.end()) {
     715             :             // r = search->second;
     716         563 :             search->second.Tables.push_back(tbl);
     717             :         } else {
     718             :             // r = new Report();
     719         226 :             Report r;
     720         113 :             r.ReportName = reportName;
     721         113 :             r.ReportForString = reportForString;
     722         113 :             r.Tables.push_back(tbl);
     723         113 :             reportsMap.emplace(key, r);
     724             :         }
     725             : 
     726             :         // Table *tbl = new Table( body, rowLabels, columnLabels, tableName, footnoteText );
     727             :         // r->Tables.push_back( tbl );
     728         676 :     }
     729             : 
     730           2 :     json ReportsCollection::getJSON() const
     731             :     {
     732           2 :         json root = json::array();
     733             : 
     734          37 :         for (auto const &iter : reportsMap) {
     735          35 :             root.push_back(iter.second.getJSON());
     736             :         }
     737           2 :         return root;
     738             :     }
     739             : 
     740          20 :     void CSVWriter::parseTSOutputs(EnergyPlusData &state,
     741             :                                    json const &data,
     742             :                                    std::vector<std::string> const &outputVariables,
     743             :                                    OutputProcessor::ReportingFrequency reportingFrequency)
     744             :     {
     745          20 :         if (data.empty()) return;
     746          16 :         updateReportingFrequency(reportingFrequency);
     747          32 :         std::vector<int> indices;
     748          32 :         std::unordered_set<std::string> seen;
     749          32 :         std::string search_string;
     750             : 
     751          32 :         std::string reportFrequency = data.at("ReportFrequency").get<std::string>();
     752          16 :         if (reportFrequency == "Detailed-HVAC" || reportFrequency == "Detailed-Zone") {
     753           6 :             reportFrequency = "Each Call";
     754             :         }
     755          16 :         auto const &columns = data.at("Cols");
     756         168 :         for (auto const &column : columns) {
     757         152 :             search_string =
     758         304 :                 fmt::format("{0} [{1}]({2})", column.at("Variable").get<std::string>(), column.at("Units").get<std::string>(), reportFrequency);
     759         304 :             auto found = std::find(outputVariables.begin(), outputVariables.end(), search_string);
     760         152 :             if (found == outputVariables.end()) {
     761           0 :                 search_string =
     762           0 :                     fmt::format("{0} [{1}]({2})", column.at("Variable").get<std::string>(), column.at("Units").get<std::string>(), "Each Call");
     763           0 :                 found = std::find(outputVariables.begin(), outputVariables.end(), search_string);
     764             :             }
     765         152 :             if (found == outputVariables.end()) {
     766           0 :                 ShowFatalError(state, fmt::format("Output variable ({0}) not found output variable list", search_string));
     767             :             }
     768         152 :             outputVariableIndices[std::distance(outputVariables.begin(), found)] = true;
     769         152 :             indices.emplace_back(std::distance(outputVariables.begin(), found));
     770             :         }
     771             : 
     772          16 :         auto const &rows = data.at("Rows");
     773        1968 :         for (auto const &row : rows) {
     774        3904 :             for (auto &el : row.items()) {
     775        3904 :                 auto found_key = outputs.find(el.key());
     776        1952 :                 if (found_key == outputs.end()) {
     777        2832 :                     std::vector<std::string> output(outputVariables.size());
     778        1416 :                     int i = 0;
     779       10659 :                     for (auto const &col : el.value()) {
     780        9243 :                         if (col.is_null()) {
     781           0 :                             output[indices[i]] = "";
     782             :                         } else {
     783        9243 :                             dtoa(col.get<double>(), s);
     784        9243 :                             output[indices[i]] = s;
     785             :                         }
     786        9243 :                         ++i;
     787             :                     }
     788        1416 :                     outputs[el.key()] = output;
     789             :                 } else {
     790         536 :                     int i = 0;
     791        1918 :                     for (auto const &col : el.value()) {
     792        1382 :                         if (col.is_null()) {
     793           0 :                             found_key->second[indices[i]] = "";
     794             :                         } else {
     795        1382 :                             dtoa(col.get<double>(), s);
     796        1382 :                             found_key->second[indices[i]] = s;
     797             :                         }
     798        1382 :                         ++i;
     799             :                     }
     800             :                 }
     801             :             }
     802             :         }
     803             :     }
     804             : 
     805          16 :     void CSVWriter::updateReportingFrequency(OutputProcessor::ReportingFrequency reportingFrequency)
     806             :     {
     807          16 :         if (reportingFrequency < smallestReportingFrequency) {
     808          13 :             smallestReportingFrequency = reportingFrequency;
     809             :         }
     810          16 :     }
     811             : 
     812           4 :     std::string &CSVWriter::convertToMonth(EnergyPlusData &state, std::string &datetime)
     813             :     {
     814             :         // if running this function, there should only ever be 12 + design days values to change
     815             :         static const std::map<std::string, std::string> months({{"01", "January"},
     816             :                                                                 {"02", "February"},
     817             :                                                                 {"03", "March"},
     818             :                                                                 {"04", "April"},
     819             :                                                                 {"05", "May"},
     820             :                                                                 {"06", "June"},
     821             :                                                                 {"07", "July"},
     822             :                                                                 {"08", "August"},
     823             :                                                                 {"09", "September"},
     824             :                                                                 {"10", "October"},
     825             :                                                                 {"11", "November"},
     826           4 :                                                                 {"12", "December"}});
     827             :         // 01/01 24:00:00
     828           8 :         auto const month = datetime.substr(0, 2);
     829           4 :         auto const pos = datetime.find(' ');
     830           8 :         std::string time;
     831           4 :         if (pos != std::string::npos) {
     832           4 :             time = datetime.substr(pos);
     833             :         }
     834           4 :         if (time != " 24:00:00") {
     835           0 :             ShowFatalError(state, "Monthly output variables should occur at the end of the day.");
     836             :         }
     837           4 :         datetime = months.find(month)->second;
     838           8 :         return datetime;
     839             :     }
     840             : 
     841             :     void
     842           7 :     CSVWriter::writeOutput(EnergyPlusData &state, std::vector<std::string> const &outputVariables, InputOutputFile &outputFile, bool outputControl)
     843             :     {
     844           7 :         outputFile.ensure_open(state, "OpenOutputFiles", outputControl);
     845             : 
     846           7 :         print<FormatSyntax::FMT>(outputFile, "{}", "Date/Time,");
     847          14 :         std::string sep;
     848         246 :         for (auto it = outputVariables.begin(); it != outputVariables.end(); ++it) {
     849         239 :             if (!outputVariableIndices[std::distance(outputVariables.begin(), it)]) continue;
     850         152 :             print<FormatSyntax::FMT>(outputFile, "{}{}", sep, *it);
     851         152 :             if (sep.empty()) sep = ",";
     852             :         }
     853           7 :         print<FormatSyntax::FMT>(outputFile, "{}", '\n');
     854             : 
     855        1423 :         for (auto &item : outputs) {
     856        2832 :             std::string datetime = item.first;
     857        1416 :             if (smallestReportingFrequency < OutputProcessor::ReportingFrequency::Monthly) {
     858        1412 :                 datetime = datetime.replace(datetime.find(' '), 1, "  ");
     859             :             } else {
     860           4 :                 convertToMonth(state, datetime);
     861             :             }
     862        1416 :             print<FormatSyntax::FMT>(outputFile, " {},", datetime);
     863        5664 :             item.second.erase(std::remove_if(item.second.begin(),
     864        2832 :                                              item.second.end(),
     865       63896 :                                              [&](const std::string &d) {
     866       63896 :                                                  auto pos = (&d - &*item.second.begin());
     867       63896 :                                                  return !outputVariableIndices[pos];
     868             :                                              }),
     869        2832 :                               item.second.end());
     870       29349 :             auto result = std::find_if(item.second.rbegin(), item.second.rend(), [](std::string const &v) { return !v.empty(); });
     871        2832 :             auto last = item.second.end() - 1;
     872        1416 :             if (result != item.second.rend()) {
     873        1416 :                 last = (result + 1).base();
     874             :             }
     875             : 
     876        1416 :             print<FormatSyntax::FMT>(outputFile, "{},", fmt::join(item.second.begin(), last, ","));
     877        1416 :             print<FormatSyntax::FMT>(outputFile, "{}\n", *last);
     878             :         }
     879             : 
     880           7 :         outputFile.close();
     881           7 :     }
     882             : 
     883         771 :     void ResultsFramework::setupOutputOptions(EnergyPlusData &state)
     884             :     {
     885         771 :         if (state.files.outputControl.csv) {
     886           4 :             tsEnabled = true;
     887           4 :             tsAndTabularEnabled = true;
     888             :         }
     889             : 
     890         771 :         if (!state.files.outputControl.json) {
     891         769 :             return;
     892             :         }
     893             : 
     894         770 :         int numberOfOutputSchemaObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Output:JSON");
     895         770 :         if (numberOfOutputSchemaObjects == 0) {
     896         767 :             return;
     897             :         }
     898             : 
     899           6 :         Array1D_string alphas(5);
     900             :         int numAlphas;
     901           6 :         Array1D<Real64> numbers(2);
     902             :         int numNumbers;
     903             :         int status;
     904           3 :         state.dataInputProcessing->inputProcessor->getObjectItem(state, "Output:JSON", 1, alphas, numAlphas, numbers, numNumbers, status);
     905             : 
     906           3 :         if (numAlphas > 0) {
     907           6 :             std::string option = alphas(1);
     908           3 :             if (UtilityRoutines::SameString(option, "TimeSeries")) {
     909           1 :                 tsEnabled = true;
     910           2 :             } else if (UtilityRoutines::SameString(option, "TimeSeriesAndTabular")) {
     911           2 :                 tsEnabled = true;
     912           2 :                 tsAndTabularEnabled = true;
     913             :             }
     914             : 
     915             :             // defaults
     916           3 :             outputJSON = true;
     917           3 :             outputCBOR = false;
     918           3 :             outputMsgPack = false;
     919             : 
     920           3 :             if (numAlphas >= 2) {
     921           2 :                 outputJSON = UtilityRoutines::SameString(alphas(2), "Yes");
     922             :             }
     923             : 
     924           3 :             if (numAlphas >= 3) {
     925           2 :                 outputCBOR = UtilityRoutines::SameString(alphas(3), "Yes");
     926             :             }
     927             : 
     928           3 :             if (numAlphas >= 4) {
     929           2 :                 outputMsgPack = UtilityRoutines::SameString(alphas(4), "Yes");
     930             :             }
     931             :         }
     932             :     }
     933             : 
     934    11647089 :     bool ResultsFramework::timeSeriesEnabled() const
     935             :     {
     936    11647089 :         return tsEnabled;
     937             :     }
     938             : 
     939      127502 :     bool ResultsFramework::timeSeriesAndTabularEnabled() const
     940             :     {
     941      127502 :         return tsAndTabularEnabled;
     942             :     }
     943             : 
     944           0 :     bool ResultsFramework::JSONEnabled() const
     945             :     {
     946           0 :         return outputJSON;
     947             :     }
     948             : 
     949           0 :     bool ResultsFramework::CBOREnabled() const
     950             :     {
     951           0 :         return outputCBOR;
     952             :     }
     953             : 
     954           0 :     bool ResultsFramework::MsgPackEnabled() const
     955             :     {
     956           0 :         return outputMsgPack;
     957             :     }
     958             : 
     959          49 :     void ResultsFramework::initializeRTSDataFrame(const OutputProcessor::ReportingFrequency reportFrequency,
     960             :                                                   const Array1D<RealVariableType> &RVariableTypes,
     961             :                                                   const int NumOfRVariable,
     962             :                                                   const OutputProcessor::TimeStepType timeStepType)
     963             :     {
     964          98 :         Reference<RealVariables> RVar;
     965             : 
     966        7812 :         for (int Loop = 1; Loop <= NumOfRVariable; ++Loop) {
     967        7763 :             RVar >>= RVariableTypes(Loop).VarPtr;
     968        7763 :             auto &rVar(RVar());
     969        7763 :             if (rVar.Report && rVar.frequency == reportFrequency) {
     970         756 :                 Variable var;
     971         378 :                 if (RVariableTypes(Loop).units == OutputProcessor::Unit::customEMS) {
     972          10 :                     var = Variable(RVariableTypes(Loop).VarName,
     973             :                                    reportFrequency,
     974           5 :                                    RVariableTypes(Loop).timeStepType,
     975           5 :                                    RVariableTypes(Loop).ReportID,
     976           5 :                                    RVariableTypes(Loop).units,
     977           5 :                                    RVariableTypes(Loop).unitNameCustomEMS);
     978             :                 } else {
     979         373 :                     var = Variable(RVariableTypes(Loop).VarName,
     980             :                                    reportFrequency,
     981         373 :                                    RVariableTypes(Loop).timeStepType,
     982         373 :                                    RVariableTypes(Loop).ReportID,
     983         373 :                                    RVariableTypes(Loop).units);
     984             :                 }
     985         378 :                 switch (reportFrequency) {
     986          52 :                 case OutputProcessor::ReportingFrequency::EachCall: // each time UpdatedataandReport is called
     987          78 :                     if ((timeStepType == OutputProcessor::TimeStepType::Zone) &&
     988          26 :                         (RVariableTypes(Loop).timeStepType == OutputProcessor::TimeStepType::Zone)) {
     989           2 :                         RIDetailedZoneTSData.setRDataFrameEnabled(true);
     990           2 :                         RIDetailedZoneTSData.addVariable(var);
     991          76 :                     } else if ((timeStepType == OutputProcessor::TimeStepType::System) &&
     992          26 :                                (RVariableTypes(Loop).timeStepType == OutputProcessor::TimeStepType::System)) {
     993          24 :                         RIDetailedHVACTSData.setRDataFrameEnabled(true);
     994          24 :                         RIDetailedHVACTSData.addVariable(var);
     995             :                     }
     996          52 :                     break;
     997           0 :                 case OutputProcessor::ReportingFrequency::TimeStep: // at 'EndTimeStepFlag'
     998           0 :                     RITimestepTSData.setRDataFrameEnabled(true);
     999           0 :                     RITimestepTSData.addVariable(var);
    1000           0 :                     break;
    1001         326 :                 case OutputProcessor::ReportingFrequency::Hourly: // at 'EndHourFlag'
    1002         326 :                     RIHourlyTSData.setRDataFrameEnabled(true);
    1003         326 :                     RIHourlyTSData.addVariable(var);
    1004         326 :                     break;
    1005           0 :                 case OutputProcessor::ReportingFrequency::Daily: // at 'EndDayFlag'
    1006           0 :                     RIDailyTSData.setRDataFrameEnabled(true);
    1007           0 :                     RIDailyTSData.addVariable(var);
    1008           0 :                     break;
    1009           0 :                 case OutputProcessor::ReportingFrequency::Monthly: // at end of month
    1010           0 :                     RIMonthlyTSData.setRDataFrameEnabled(true);
    1011           0 :                     RIMonthlyTSData.addVariable(var);
    1012           0 :                     break;
    1013           0 :                 case OutputProcessor::ReportingFrequency::Simulation: // once per environment 'EndEnvrnFlag'
    1014           0 :                     RIRunPeriodTSData.setRDataFrameEnabled(true);
    1015           0 :                     RIRunPeriodTSData.addVariable(var);
    1016           0 :                     break;
    1017           0 :                 case OutputProcessor::ReportingFrequency::Yearly: // at end of year
    1018           0 :                     RIYearlyTSData.setRDataFrameEnabled(true);
    1019           0 :                     RIYearlyTSData.addVariable(var);
    1020           0 :                     break;
    1021           0 :                 default:
    1022           0 :                     assert(false);
    1023             :                 }
    1024             :             }
    1025             :         }
    1026             :         // set the scanned variables to true or false
    1027          49 :         switch (reportFrequency) {
    1028          14 :         case OutputProcessor::ReportingFrequency::EachCall:
    1029          14 :             if (timeStepType == OutputProcessor::TimeStepType::Zone) {
    1030           7 :                 RIDetailedZoneTSData.setRVariablesScanned(true);
    1031           7 :             } else if (timeStepType == OutputProcessor::TimeStepType::System) {
    1032           7 :                 RIDetailedHVACTSData.setRVariablesScanned(true);
    1033             :             }
    1034          14 :             break;
    1035           7 :         case OutputProcessor::ReportingFrequency::TimeStep: // at 'EndTimeStepFlag'
    1036           7 :             RITimestepTSData.setRVariablesScanned(true);
    1037           7 :             break;
    1038           7 :         case OutputProcessor::ReportingFrequency::Hourly: // at 'EndHourFlag'
    1039           7 :             RIHourlyTSData.setRVariablesScanned(true);
    1040           7 :             break;
    1041           7 :         case OutputProcessor::ReportingFrequency::Daily: // at 'EndDayFlag'
    1042           7 :             RIDailyTSData.setRVariablesScanned(true);
    1043           7 :             break;
    1044           7 :         case OutputProcessor::ReportingFrequency::Monthly: // at end of month
    1045           7 :             RIMonthlyTSData.setRVariablesScanned(true);
    1046           7 :             break;
    1047           7 :         case OutputProcessor::ReportingFrequency::Simulation: // once per environment 'EndEnvrnFlag'
    1048           7 :             RIRunPeriodTSData.setRVariablesScanned(true);
    1049           7 :             break;
    1050           0 :         case OutputProcessor::ReportingFrequency::Yearly: // at end of year
    1051           0 :             RIYearlyTSData.setRVariablesScanned(true);
    1052           0 :             break;
    1053           0 :         default:
    1054           0 :             assert(false);
    1055             :         }
    1056          49 :     }
    1057             : 
    1058          49 :     void ResultsFramework::initializeITSDataFrame(const OutputProcessor::ReportingFrequency reportFrequency,
    1059             :                                                   const Array1D<IntegerVariableType> &IVariableTypes,
    1060             :                                                   const int NumOfIVariable,
    1061             :                                                   const OutputProcessor::TimeStepType timeStepType)
    1062             :     {
    1063          98 :         Reference<IntegerVariables> IVar;
    1064             : 
    1065             :         // loop over values to suck in var info
    1066         238 :         for (int Loop = 1; Loop <= NumOfIVariable; ++Loop) {
    1067         189 :             IVar >>= IVariableTypes(Loop).VarPtr;
    1068         189 :             auto &iVar(IVar());
    1069         189 :             if (iVar.Report && iVar.frequency == reportFrequency) {
    1070          30 :                 OutputVariable var(IVariableTypes(Loop).VarName,
    1071             :                                    reportFrequency,
    1072          30 :                                    IVariableTypes(Loop).timeStepType,
    1073          30 :                                    IVariableTypes(Loop).ReportID,
    1074          90 :                                    IVariableTypes(Loop).units);
    1075          30 :                 switch (reportFrequency) {
    1076           6 :                 case OutputProcessor::ReportingFrequency::EachCall: // each time UpdatedataandReport is called
    1077           9 :                     if ((timeStepType == OutputProcessor::TimeStepType::Zone) &&
    1078           3 :                         (IVariableTypes(Loop).timeStepType == OutputProcessor::TimeStepType::Zone)) {
    1079           0 :                         RIDetailedZoneTSData.setIDataFrameEnabled(true);
    1080           0 :                         RIDetailedZoneTSData.addVariable(var);
    1081           9 :                     } else if ((timeStepType == OutputProcessor::TimeStepType::System) &&
    1082           3 :                                (IVariableTypes(Loop).timeStepType == OutputProcessor::TimeStepType::System)) {
    1083           3 :                         RIDetailedHVACTSData.setIDataFrameEnabled(true);
    1084           3 :                         RIDetailedHVACTSData.addVariable(var);
    1085             :                     }
    1086           6 :                     break;
    1087           0 :                 case OutputProcessor::ReportingFrequency::TimeStep: // at 'EndTimeStepFlag'
    1088           0 :                     RITimestepTSData.setIDataFrameEnabled(true);
    1089           0 :                     RITimestepTSData.addVariable(var);
    1090           0 :                     break;
    1091          24 :                 case OutputProcessor::ReportingFrequency::Hourly: // at 'EndHourFlag'
    1092          24 :                     RIHourlyTSData.setIDataFrameEnabled(true);
    1093          24 :                     RIHourlyTSData.addVariable(var);
    1094          24 :                     break;
    1095           0 :                 case OutputProcessor::ReportingFrequency::Daily: // at 'EndDayFlag'
    1096           0 :                     RIDailyTSData.setIDataFrameEnabled(true);
    1097           0 :                     RIDailyTSData.addVariable(var);
    1098           0 :                     break;
    1099           0 :                 case OutputProcessor::ReportingFrequency::Monthly: // at end of month
    1100           0 :                     RIMonthlyTSData.setIDataFrameEnabled(true);
    1101           0 :                     RIMonthlyTSData.addVariable(var);
    1102           0 :                     break;
    1103           0 :                 case OutputProcessor::ReportingFrequency::Simulation: // once per environment 'EndEnvrnFlag'
    1104           0 :                     RIRunPeriodTSData.setIDataFrameEnabled(true);
    1105           0 :                     RIRunPeriodTSData.addVariable(var);
    1106           0 :                     break;
    1107           0 :                 case OutputProcessor::ReportingFrequency::Yearly: // once per environment 'EndEnvrnFlag'
    1108           0 :                     RIYearlyTSData.setIDataFrameEnabled(true);
    1109           0 :                     RIYearlyTSData.addVariable(var);
    1110           0 :                     break;
    1111           0 :                 default:
    1112           0 :                     assert(false);
    1113             :                 }
    1114             :             }
    1115             :         }
    1116             : 
    1117             :         // set the scanned variables to true or false
    1118          49 :         switch (reportFrequency) {
    1119          14 :         case OutputProcessor::ReportingFrequency::EachCall:
    1120          14 :             if (timeStepType == OutputProcessor::TimeStepType::Zone) {
    1121           7 :                 RIDetailedZoneTSData.setIVariablesScanned(true);
    1122           7 :             } else if (timeStepType == OutputProcessor::TimeStepType::System) {
    1123           7 :                 RIDetailedHVACTSData.setIVariablesScanned(true);
    1124             :             }
    1125          14 :             break;
    1126           7 :         case OutputProcessor::ReportingFrequency::TimeStep: // at 'EndTimeStepFlag'
    1127           7 :             RITimestepTSData.setIVariablesScanned(true);
    1128           7 :             break;
    1129           7 :         case OutputProcessor::ReportingFrequency::Hourly: // at 'EndHourFlag'
    1130           7 :             RIHourlyTSData.setIVariablesScanned(true);
    1131           7 :             break;
    1132           7 :         case OutputProcessor::ReportingFrequency::Daily: // at 'EndDayFlag'
    1133           7 :             RIDailyTSData.setIVariablesScanned(true);
    1134           7 :             break;
    1135           7 :         case OutputProcessor::ReportingFrequency::Monthly: // at end of month
    1136           7 :             RIMonthlyTSData.setIVariablesScanned(true);
    1137           7 :             break;
    1138           7 :         case OutputProcessor::ReportingFrequency::Simulation: // once per environment 'EndEnvrnFlag'
    1139           7 :             RIRunPeriodTSData.setIVariablesScanned(true);
    1140           7 :             break;
    1141           0 :         case OutputProcessor::ReportingFrequency::Yearly: // once per environment 'EndEnvrnFlag'
    1142           0 :             RIYearlyTSData.setIVariablesScanned(true);
    1143           0 :             break;
    1144           0 :         default:
    1145           0 :             assert(false);
    1146             :         }
    1147          49 :     }
    1148             : 
    1149      345735 :     void ResultsFramework::initializeMeters(const Array1D<OutputProcessor::MeterType> &EnergyMeters,
    1150             :                                             const OutputProcessor::ReportingFrequency reportFrequency)
    1151             :     {
    1152      345735 :         switch (reportFrequency) {
    1153           0 :         case OutputProcessor::ReportingFrequency::EachCall:
    1154             :             // nothing to do; meters are not reported at this frequency
    1155           0 :             break;
    1156      293532 :         case OutputProcessor::ReportingFrequency::TimeStep: // at 'TimeStep'
    1157    35540740 :             for (auto Loop = 1; Loop <= EnergyMeters.isize(); ++Loop) {
    1158    35247208 :                 if (EnergyMeters(Loop).RptTS || EnergyMeters(Loop).RptTSFO) {
    1159             :                     MeterVariable var(
    1160         100 :                         EnergyMeters(Loop).Name, reportFrequency, EnergyMeters(Loop).TSRptNum, EnergyMeters(Loop).Units, EnergyMeters(Loop).RptTSFO);
    1161          50 :                     TSMeters.addVariable(var);
    1162          50 :                     TSMeters.setRDataFrameEnabled(true);
    1163             :                 }
    1164    35247208 :                 if (EnergyMeters(Loop).RptAccTS || EnergyMeters(Loop).RptAccTSFO) {
    1165           0 :                     MeterVariable var(EnergyMeters(Loop).Name,
    1166             :                                       reportFrequency,
    1167           0 :                                       EnergyMeters(Loop).TSAccRptNum,
    1168           0 :                                       EnergyMeters(Loop).Units,
    1169           0 :                                       EnergyMeters(Loop).RptAccTSFO);
    1170           0 :                     TSMeters.addVariable(var);
    1171           0 :                     TSMeters.setRDataFrameEnabled(true);
    1172             :                 }
    1173      293532 :             }
    1174      293532 :             break;
    1175       49894 :         case OutputProcessor::ReportingFrequency::Hourly: // at 'Hourly'
    1176     5504839 :             for (auto Loop = 1; Loop <= EnergyMeters.isize(); ++Loop) {
    1177     5454945 :                 if (EnergyMeters(Loop).RptHR || EnergyMeters(Loop).RptHRFO) {
    1178             :                     MeterVariable var(
    1179        1398 :                         EnergyMeters(Loop).Name, reportFrequency, EnergyMeters(Loop).HRRptNum, EnergyMeters(Loop).Units, EnergyMeters(Loop).RptHRFO);
    1180         699 :                     HRMeters.addVariable(var);
    1181         699 :                     HRMeters.setRDataFrameEnabled(true);
    1182             :                 }
    1183     5454945 :                 if (EnergyMeters(Loop).RptAccHR || EnergyMeters(Loop).RptAccHRFO) {
    1184           0 :                     MeterVariable var(EnergyMeters(Loop).Name,
    1185             :                                       reportFrequency,
    1186           0 :                                       EnergyMeters(Loop).HRAccRptNum,
    1187           0 :                                       EnergyMeters(Loop).Units,
    1188           0 :                                       EnergyMeters(Loop).RptAccHRFO);
    1189           0 :                     HRMeters.addVariable(var);
    1190           0 :                     HRMeters.setRDataFrameEnabled(true);
    1191             :                 }
    1192       49894 :             }
    1193       49894 :             break;
    1194         769 :         case OutputProcessor::ReportingFrequency::Daily: // at 'Daily'
    1195       93658 :             for (auto Loop = 1; Loop <= EnergyMeters.isize(); ++Loop) {
    1196       92889 :                 if (EnergyMeters(Loop).RptDY || EnergyMeters(Loop).RptDYFO) {
    1197             :                     MeterVariable var(
    1198         142 :                         EnergyMeters(Loop).Name, reportFrequency, EnergyMeters(Loop).DYRptNum, EnergyMeters(Loop).Units, EnergyMeters(Loop).RptDYFO);
    1199          71 :                     DYMeters.addVariable(var);
    1200          71 :                     DYMeters.setRDataFrameEnabled(true);
    1201             :                 }
    1202       92889 :                 if (EnergyMeters(Loop).RptAccDY || EnergyMeters(Loop).RptAccDYFO) {
    1203           0 :                     MeterVariable var(EnergyMeters(Loop).Name,
    1204             :                                       reportFrequency,
    1205           0 :                                       EnergyMeters(Loop).DYAccRptNum,
    1206           0 :                                       EnergyMeters(Loop).Units,
    1207           0 :                                       EnergyMeters(Loop).RptAccDYFO);
    1208           0 :                     DYMeters.addVariable(var);
    1209           0 :                     DYMeters.setRDataFrameEnabled(true);
    1210             :                 }
    1211         769 :             }
    1212         769 :             break;
    1213         769 :         case OutputProcessor::ReportingFrequency::Monthly: // at 'Monthly'
    1214       93658 :             for (auto Loop = 1; Loop <= EnergyMeters.isize(); ++Loop) {
    1215       92889 :                 if (EnergyMeters(Loop).RptMN || EnergyMeters(Loop).RptMNFO) {
    1216             :                     MeterVariable var(
    1217        8170 :                         EnergyMeters(Loop).Name, reportFrequency, EnergyMeters(Loop).MNRptNum, EnergyMeters(Loop).Units, EnergyMeters(Loop).RptMNFO);
    1218        4085 :                     MNMeters.addVariable(var);
    1219        4085 :                     MNMeters.setRDataFrameEnabled(true);
    1220             :                 }
    1221       92889 :                 if (EnergyMeters(Loop).RptAccMN || EnergyMeters(Loop).RptAccMNFO) {
    1222           5 :                     MeterVariable var(EnergyMeters(Loop).Name,
    1223             :                                       reportFrequency,
    1224           5 :                                       EnergyMeters(Loop).MNAccRptNum,
    1225           5 :                                       EnergyMeters(Loop).Units,
    1226          15 :                                       EnergyMeters(Loop).RptAccMNFO);
    1227           5 :                     MNMeters.addVariable(var);
    1228           5 :                     MNMeters.setRDataFrameEnabled(true);
    1229             :                 }
    1230         769 :             }
    1231         769 :             break;
    1232         769 :         case OutputProcessor::ReportingFrequency::Simulation: // at 'RunPeriod'/'SM'
    1233       93658 :             for (auto Loop = 1; Loop <= EnergyMeters.isize(); ++Loop) {
    1234       92889 :                 if (EnergyMeters(Loop).RptSM || EnergyMeters(Loop).RptSMFO) {
    1235             :                     MeterVariable var(
    1236        5648 :                         EnergyMeters(Loop).Name, reportFrequency, EnergyMeters(Loop).SMRptNum, EnergyMeters(Loop).Units, EnergyMeters(Loop).RptSMFO);
    1237        2824 :                     SMMeters.addVariable(var);
    1238        2824 :                     SMMeters.setRDataFrameEnabled(true);
    1239             :                 }
    1240       92889 :                 if (EnergyMeters(Loop).RptAccSM || EnergyMeters(Loop).RptAccSMFO) {
    1241           0 :                     MeterVariable var(EnergyMeters(Loop).Name,
    1242             :                                       reportFrequency,
    1243           0 :                                       EnergyMeters(Loop).SMAccRptNum,
    1244           0 :                                       EnergyMeters(Loop).Units,
    1245           0 :                                       EnergyMeters(Loop).RptAccSMFO);
    1246           0 :                     SMMeters.addVariable(var);
    1247           0 :                     SMMeters.setRDataFrameEnabled(true);
    1248             :                 }
    1249         769 :             }
    1250         769 :             break;
    1251           2 :         case OutputProcessor::ReportingFrequency::Yearly: // at 'Yearly'
    1252         236 :             for (auto Loop = 1; Loop <= EnergyMeters.isize(); ++Loop) {
    1253         234 :                 if (EnergyMeters(Loop).RptYR || EnergyMeters(Loop).RptYRFO) {
    1254             :                     MeterVariable var(
    1255           0 :                         EnergyMeters(Loop).Name, reportFrequency, EnergyMeters(Loop).YRRptNum, EnergyMeters(Loop).Units, EnergyMeters(Loop).RptYRFO);
    1256           0 :                     YRMeters.addVariable(var);
    1257           0 :                     YRMeters.setRDataFrameEnabled(true);
    1258             :                 }
    1259         234 :                 if (EnergyMeters(Loop).RptAccYR || EnergyMeters(Loop).RptAccYRFO) {
    1260           0 :                     MeterVariable var(EnergyMeters(Loop).Name,
    1261             :                                       reportFrequency,
    1262           0 :                                       EnergyMeters(Loop).YRAccRptNum,
    1263           0 :                                       EnergyMeters(Loop).Units,
    1264           0 :                                       EnergyMeters(Loop).RptAccDYFO);
    1265           0 :                     YRMeters.addVariable(var);
    1266           0 :                     YRMeters.setRDataFrameEnabled(true);
    1267             :                 }
    1268           2 :             }
    1269           2 :             break;
    1270           0 :         default:
    1271           0 :             assert(false);
    1272             :         }
    1273             : 
    1274             :         // set the scanned variables to true or false
    1275      345735 :         switch (reportFrequency) {
    1276           0 :         case OutputProcessor::ReportingFrequency::EachCall:
    1277             :             // case should not happen in Meters
    1278           0 :             break;
    1279      293532 :         case OutputProcessor::ReportingFrequency::TimeStep: // at TimeStepFlag
    1280      293532 :             TSMeters.setRVariablesScanned(true);
    1281      293532 :             break;
    1282       49894 :         case OutputProcessor::ReportingFrequency::Hourly: // at Hourly
    1283       49894 :             HRMeters.setRVariablesScanned(true);
    1284       49894 :             break;
    1285         769 :         case OutputProcessor::ReportingFrequency::Daily: // at Daily
    1286         769 :             DYMeters.setRVariablesScanned(true);
    1287         769 :             break;
    1288         769 :         case OutputProcessor::ReportingFrequency::Monthly: // at Monthly
    1289         769 :             MNMeters.setRVariablesScanned(true);
    1290         769 :             break;
    1291         769 :         case OutputProcessor::ReportingFrequency::Simulation: // at RunPeriod/SM
    1292         769 :             SMMeters.setRVariablesScanned(true);
    1293         769 :             break;
    1294           2 :         case OutputProcessor::ReportingFrequency::Yearly: // at Yearly
    1295           2 :             YRMeters.setRVariablesScanned(true);
    1296           2 :             break;
    1297           0 :         default:
    1298           0 :             assert(false);
    1299             :         }
    1300      345735 :     }
    1301             : 
    1302         771 :     void ResultsFramework::writeOutputs(EnergyPlusData &state)
    1303             :     {
    1304         771 :         if (state.files.outputControl.csv) {
    1305           4 :             writeCSVOutput(state);
    1306             :         }
    1307             : 
    1308         771 :         if (timeSeriesEnabled() && (outputJSON || outputCBOR || outputMsgPack)) {
    1309           3 :             writeTimeSeriesReports(state.files.json);
    1310             :         }
    1311             : 
    1312         771 :         if (timeSeriesAndTabularEnabled() && (outputJSON || outputCBOR || outputMsgPack)) {
    1313           2 :             writeReport(state.files.json);
    1314             :         }
    1315         771 :     }
    1316             : 
    1317           4 :     void ResultsFramework::writeCSVOutput(EnergyPlusData &state)
    1318             :     {
    1319           4 :         if (!hasOutputData()) {
    1320           0 :             return;
    1321             :         }
    1322           8 :         CSVWriter csv(outputVariables.size());
    1323           8 :         CSVWriter mtr_csv(outputVariables.size());
    1324             : 
    1325             :         // Output yearly time series data
    1326           4 :         if (hasRIYearlyTSData()) {
    1327           0 :             csv.parseTSOutputs(state, RIYearlyTSData.getJSON(), outputVariables, OutputProcessor::ReportingFrequency::Yearly);
    1328             :         }
    1329             : 
    1330           4 :         if (hasYRMeters()) {
    1331           0 :             csv.parseTSOutputs(state, YRMeters.getJSON(true), outputVariables, OutputProcessor::ReportingFrequency::Yearly);
    1332           0 :             mtr_csv.parseTSOutputs(state, YRMeters.getJSON(), outputVariables, OutputProcessor::ReportingFrequency::Yearly);
    1333             :         }
    1334             : 
    1335             :         // Output run period time series data
    1336           4 :         if (hasRIRunPeriodTSData()) {
    1337           0 :             csv.parseTSOutputs(state, RIRunPeriodTSData.getJSON(), outputVariables, OutputProcessor::ReportingFrequency::Simulation);
    1338             :         }
    1339             : 
    1340           4 :         if (hasSMMeters()) {
    1341           2 :             csv.parseTSOutputs(state, SMMeters.getJSON(true), outputVariables, OutputProcessor::ReportingFrequency::Simulation);
    1342           2 :             mtr_csv.parseTSOutputs(state, SMMeters.getJSON(), outputVariables, OutputProcessor::ReportingFrequency::Simulation);
    1343             :         }
    1344             : 
    1345             :         // Output monthly time series data
    1346           4 :         if (hasRIMonthlyTSData()) {
    1347           0 :             csv.parseTSOutputs(state, RIMonthlyTSData.getJSON(), outputVariables, OutputProcessor::ReportingFrequency::Monthly);
    1348             :         }
    1349             : 
    1350           4 :         if (hasMNMeters()) {
    1351           3 :             csv.parseTSOutputs(state, MNMeters.getJSON(true), outputVariables, OutputProcessor::ReportingFrequency::Monthly);
    1352           3 :             mtr_csv.parseTSOutputs(state, MNMeters.getJSON(), outputVariables, OutputProcessor::ReportingFrequency::Monthly);
    1353             :         }
    1354             : 
    1355             :         // Output daily time series data
    1356           4 :         if (hasRIDailyTSData()) {
    1357           0 :             csv.parseTSOutputs(state, RIDailyTSData.getJSON(), outputVariables, OutputProcessor::ReportingFrequency::Daily);
    1358             :         }
    1359             : 
    1360           4 :         if (hasDYMeters()) {
    1361           0 :             csv.parseTSOutputs(state, DYMeters.getJSON(true), outputVariables, OutputProcessor::ReportingFrequency::Daily);
    1362           0 :             mtr_csv.parseTSOutputs(state, DYMeters.getJSON(), outputVariables, OutputProcessor::ReportingFrequency::Daily);
    1363             :         }
    1364             : 
    1365             :         // Output hourly time series data
    1366           4 :         if (hasRIHourlyTSData()) {
    1367           2 :             csv.parseTSOutputs(state, RIHourlyTSData.getJSON(), outputVariables, OutputProcessor::ReportingFrequency::Hourly);
    1368             :         }
    1369             : 
    1370           4 :         if (hasHRMeters()) {
    1371           1 :             csv.parseTSOutputs(state, HRMeters.getJSON(true), outputVariables, OutputProcessor::ReportingFrequency::Hourly);
    1372           1 :             mtr_csv.parseTSOutputs(state, HRMeters.getJSON(), outputVariables, OutputProcessor::ReportingFrequency::Hourly);
    1373             :         }
    1374             : 
    1375             :         // Output timestep time series data
    1376           4 :         if (hasRITimestepTSData()) {
    1377           0 :             csv.parseTSOutputs(state, RITimestepTSData.getJSON(), outputVariables, OutputProcessor::ReportingFrequency::TimeStep);
    1378             :         }
    1379             : 
    1380           4 :         if (hasTSMeters()) {
    1381           0 :             csv.parseTSOutputs(state, TSMeters.getJSON(true), outputVariables, OutputProcessor::ReportingFrequency::TimeStep);
    1382           0 :             mtr_csv.parseTSOutputs(state, TSMeters.getJSON(), outputVariables, OutputProcessor::ReportingFrequency::TimeStep);
    1383             :         }
    1384             : 
    1385             :         // Output detailed HVAC time series data
    1386           4 :         if (hasRIDetailedHVACTSData()) {
    1387           4 :             csv.parseTSOutputs(state, RIDetailedHVACTSData.getJSON(), outputVariables, OutputProcessor::ReportingFrequency::EachCall);
    1388             :         }
    1389             : 
    1390             :         // Output detailed Zone time series data
    1391           4 :         if (hasRIDetailedZoneTSData()) {
    1392           2 :             csv.parseTSOutputs(state, RIDetailedZoneTSData.getJSON(), outputVariables, OutputProcessor::ReportingFrequency::EachCall);
    1393             :         }
    1394             : 
    1395           4 :         csv.writeOutput(state, outputVariables, state.files.csv, state.files.outputControl.csv);
    1396           4 :         if (hasMeterData()) {
    1397           3 :             mtr_csv.writeOutput(state, outputVariables, state.files.mtr_csv, state.files.outputControl.csv);
    1398             :         }
    1399             :     }
    1400             : 
    1401           3 :     void ResultsFramework::writeTimeSeriesReports(JsonOutputFilePaths &jsonOutputFilePaths)
    1402             :     {
    1403             :         // Output detailed Zone time series data
    1404           3 :         if (hasRIDetailedZoneTSData()) {
    1405           0 :             RIDetailedZoneTSData.writeReport(jsonOutputFilePaths, outputJSON, outputCBOR, outputMsgPack);
    1406             :         }
    1407             : 
    1408             :         // Output detailed HVAC time series data
    1409           3 :         if (hasRIDetailedHVACTSData()) {
    1410           1 :             RIDetailedHVACTSData.writeReport(jsonOutputFilePaths, outputJSON, outputCBOR, outputMsgPack);
    1411             :         }
    1412             : 
    1413             :         // Output timestep time series data
    1414           3 :         if (hasRITimestepTSData()) {
    1415           0 :             RITimestepTSData.writeReport(jsonOutputFilePaths, outputJSON, outputCBOR, outputMsgPack);
    1416             :         }
    1417             : 
    1418             :         // Output hourly time series data
    1419           3 :         if (hasRIHourlyTSData()) {
    1420           3 :             RIHourlyTSData.writeReport(jsonOutputFilePaths, outputJSON, outputCBOR, outputMsgPack);
    1421             :         }
    1422             : 
    1423             :         // Output daily time series data
    1424           3 :         if (hasRIDailyTSData()) {
    1425           0 :             RIDailyTSData.writeReport(jsonOutputFilePaths, outputJSON, outputCBOR, outputMsgPack);
    1426             :         }
    1427             : 
    1428             :         // Output monthly time series data
    1429           3 :         if (hasRIMonthlyTSData()) {
    1430           0 :             RIMonthlyTSData.writeReport(jsonOutputFilePaths, outputJSON, outputCBOR, outputMsgPack);
    1431             :         }
    1432             : 
    1433             :         // Output run period time series data
    1434           3 :         if (hasRIRunPeriodTSData()) {
    1435           0 :             RIRunPeriodTSData.writeReport(jsonOutputFilePaths, outputJSON, outputCBOR, outputMsgPack);
    1436             :         }
    1437             : 
    1438             :         // Output yearly time series data
    1439           3 :         if (hasRIYearlyTSData()) {
    1440           0 :             RIYearlyTSData.writeReport(jsonOutputFilePaths, outputJSON, outputCBOR, outputMsgPack);
    1441             :         }
    1442           3 :     }
    1443             : 
    1444           2 :     void ResultsFramework::writeReport(JsonOutputFilePaths &jsonOutputFilePaths)
    1445             :     {
    1446           4 :         json root, outputVars, meterVars, meterData;
    1447           2 :         root = {{"SimulationResults", {{"Simulation", SimulationInformation.getJSON()}}}};
    1448             : 
    1449             :         // output variables
    1450           2 :         if (hasRIDetailedZoneTSData()) {
    1451           0 :             outputVars["Detailed-Zone"] = RIDetailedZoneTSData.getVariablesJSON();
    1452             :         }
    1453             : 
    1454           2 :         if (hasRIDetailedHVACTSData()) {
    1455           1 :             outputVars["Detailed-HVAC"] = RIDetailedHVACTSData.getVariablesJSON();
    1456             :         }
    1457             : 
    1458           2 :         if (hasRITimestepTSData()) {
    1459           0 :             outputVars["TimeStep"] = RITimestepTSData.getVariablesJSON();
    1460             :         }
    1461             : 
    1462           2 :         if (hasRIHourlyTSData()) {
    1463           2 :             outputVars["Hourly"] = RIHourlyTSData.getVariablesJSON();
    1464             :         }
    1465             : 
    1466           2 :         if (hasRIDailyTSData()) {
    1467           0 :             outputVars["Daily"], RIDailyTSData.getVariablesJSON();
    1468             :         }
    1469             : 
    1470           2 :         if (hasRIMonthlyTSData()) {
    1471           0 :             outputVars["Monthly"] = RIMonthlyTSData.getVariablesJSON();
    1472             :         }
    1473             : 
    1474           2 :         if (hasRIRunPeriodTSData()) {
    1475           0 :             outputVars["RunPeriod"] = RIRunPeriodTSData.getVariablesJSON();
    1476             :         }
    1477             : 
    1478           2 :         if (hasRIYearlyTSData()) {
    1479           0 :             outputVars["Yearly"] = RIYearlyTSData.getVariablesJSON();
    1480             :         }
    1481             : 
    1482             :         // output dictionary
    1483           2 :         outputVars["OutputDictionary"] = {{"Description", "Dictionary containing output variables that may be requested"}, {"Variables", RDD}};
    1484             : 
    1485             :         // meter variables
    1486             : 
    1487             :         // -- meter values
    1488           2 :         if (hasTSMeters()) {
    1489           0 :             meterVars["TimeStep"] = TSMeters.getVariablesJSON();
    1490             :         }
    1491             : 
    1492           2 :         if (hasHRMeters()) {
    1493           1 :             meterVars["Hourly"] = HRMeters.getVariablesJSON();
    1494             :         }
    1495             : 
    1496           2 :         if (hasDYMeters()) {
    1497           0 :             meterVars["Daily"] = DYMeters.getVariablesJSON();
    1498             :         }
    1499             : 
    1500           2 :         if (hasMNMeters()) {
    1501           2 :             meterVars["Monthly"] = MNMeters.getVariablesJSON();
    1502             :         }
    1503             : 
    1504           2 :         if (hasSMMeters()) {
    1505           1 :             meterVars["RunPeriod"] = SMMeters.getVariablesJSON();
    1506             :         }
    1507             : 
    1508           2 :         if (hasYRMeters()) {
    1509           0 :             meterVars["Yearly"] = YRMeters.getVariablesJSON();
    1510             :         }
    1511             : 
    1512           2 :         if (hasTSMeters()) {
    1513           0 :             meterData["TimeStep"] = TSMeters.getJSON();
    1514             :         }
    1515             : 
    1516           2 :         if (hasHRMeters()) {
    1517           1 :             meterData["Hourly"] = HRMeters.getJSON();
    1518             :         }
    1519             : 
    1520           2 :         if (hasDYMeters()) {
    1521           0 :             meterData["Daily"] = DYMeters.getJSON();
    1522             :         }
    1523             : 
    1524           2 :         if (hasMNMeters()) {
    1525           2 :             meterData["Monthly"] = MNMeters.getJSON();
    1526             :         }
    1527             : 
    1528           2 :         if (hasSMMeters()) {
    1529           1 :             meterData["RunPeriod"] = SMMeters.getJSON();
    1530             :         }
    1531             : 
    1532           2 :         if (hasYRMeters()) {
    1533           0 :             meterData["Yearly"] = YRMeters.getJSON();
    1534             :         }
    1535             : 
    1536             :         // -- meter dictionary
    1537           2 :         meterVars["MeterDictionary"] = {{"Description", "Dictionary containing meter variables that may be requested"}, {"Meters", MDD}};
    1538             : 
    1539           2 :         root["OutputVariables"] = outputVars;
    1540           2 :         root["MeterVariables"] = meterVars;
    1541           2 :         root["MeterData"] = meterData;
    1542           2 :         root["TabularReports"] = TabularReportsCollection.getJSON();
    1543             : 
    1544           2 :         if (outputJSON) {
    1545           2 :             FileSystem::writeFile<FileSystem::FileTypes::JSON>(jsonOutputFilePaths.outputJsonFilePath, root);
    1546             :         }
    1547           2 :         if (outputCBOR) {
    1548           1 :             FileSystem::writeFile<FileSystem::FileTypes::CBOR>(jsonOutputFilePaths.outputCborFilePath, root);
    1549             :         }
    1550           2 :         if (outputMsgPack) {
    1551           1 :             FileSystem::writeFile<FileSystem::FileTypes::MsgPack>(jsonOutputFilePaths.outputMsgPackFilePath, root);
    1552             :         }
    1553           2 :     }
    1554             : 
    1555       58444 :     void ResultsFramework::addReportVariable(std::string_view const keyedValue,
    1556             :                                              std::string_view const variableName,
    1557             :                                              std::string const &units,
    1558             :                                              OutputProcessor::ReportingFrequency const reportingInterval)
    1559             :     {
    1560      116888 :         outputVariables.emplace_back(fmt::format("{0}:{1} [{2}]({3})", keyedValue, variableName, units, reportingFrequency(reportingInterval)));
    1561       58444 :     }
    1562             : 
    1563             :     void
    1564        7818 :     ResultsFramework::addReportMeter(std::string const &meter, std::string const &units, OutputProcessor::ReportingFrequency const reportingInterval)
    1565             :     {
    1566       15636 :         outputVariables.emplace_back(fmt::format("{0} [{1}]({2})", meter, units, reportingFrequency(reportingInterval)));
    1567        7818 :     }
    1568             : 
    1569             : } // namespace ResultsFramework
    1570             : 
    1571        2313 : } // namespace EnergyPlus

Generated by: LCOV version 1.13