LCOV - code coverage report
Current view: top level - EnergyPlus - OutputReportTabularAnnual.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 54 903 6.0 %
Date: 2023-01-17 19:17:23 Functions: 7 32 21.9 %

          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 <list>
      51             : #include <ostream>
      52             : #include <string>
      53             : #include <vector>
      54             : 
      55             : // ObjexxFCL Headers
      56             : #include <ObjexxFCL/Array1D.hh>
      57             : #include <ObjexxFCL/Array2D.hh>
      58             : #include <ObjexxFCL/Array2S.hh>
      59             : #include <ObjexxFCL/Array3D.hh>
      60             : #include <ObjexxFCL/Optional.hh>
      61             : 
      62             : // EnergyPlus Headers
      63             : #include <EnergyPlus/CostEstimateManager.hh>
      64             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      65             : #include <EnergyPlus/DataEnvironment.hh>
      66             : #include <EnergyPlus/DataHVACGlobals.hh>
      67             : #include <EnergyPlus/General.hh>
      68             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      69             : #include <EnergyPlus/OutputProcessor.hh>
      70             : #include <EnergyPlus/OutputReportData.hh>
      71             : #include <EnergyPlus/OutputReportTabular.hh>
      72             : #include <EnergyPlus/OutputReportTabularAnnual.hh>
      73             : #include <EnergyPlus/SQLiteProcedures.hh>
      74             : #include <EnergyPlus/ScheduleManager.hh>
      75             : #include <EnergyPlus/UtilityRoutines.hh>
      76             : 
      77             : namespace EnergyPlus::OutputReportTabularAnnual {
      78             : 
      79         769 : void GetInputTabularAnnual(EnergyPlusData &state)
      80             : {
      81             :     // Jason Glazer, August 2015
      82             :     // The function assigns the input information for
      83             :     // REPORT:TABLE:ANNUAL also known as row per object
      84             :     // reports that are defined by the user. The input
      85             :     // information is assigned to a data structure that
      86             :     // is used for both user defined monthly reports and
      87             :     // predefined monthly reports.
      88             : 
      89         769 :     static std::string const currentModuleObject("Output:Table:Annual");
      90             : 
      91             :     int jAlpha;
      92             :     int numParams;            // Number of elements combined
      93             :     int numAlphas;            // Number of elements in the alpha array
      94             :     int numNums;              // Number of elements in the numeric array
      95        1537 :     Array1D_string alphArray; // character string data
      96        1537 :     Array1D<Real64> numArray; // numeric data
      97             :     int IOStat;               // IO Status when calling get input subroutine
      98             :     // static bool ErrorsFound( false );
      99         769 :     int objCount(0);
     100         769 :     int indexNums(0);
     101        1537 :     std::string curVarMtr("");
     102        1537 :     std::string curAggTyp("");
     103         769 :     int curNumDgts(2);
     104         769 :     AnnualFieldSet::AggregationKind curAgg(AnnualFieldSet::AggregationKind::sumOrAvg);
     105             : 
     106         769 :     auto &annualTables(state.dataOutputReportTabularAnnual->annualTables);
     107             : 
     108         769 :     objCount = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, currentModuleObject);
     109         769 :     if (objCount > 0) {
     110             : 
     111           1 :         state.dataOutRptTab->WriteTabularFiles = true;
     112             : 
     113             :         // if not a run period using weather do not create reports
     114           1 :         if (!state.dataGlobal->DoWeathSim) {
     115           3 :             ShowWarningError(state,
     116           2 :                              currentModuleObject + " requested with SimulationControl Run Simulation for Weather File Run Periods set to No so " +
     117           2 :                                  currentModuleObject + " will not be generated");
     118           1 :             return;
     119             :         }
     120             :     }
     121         768 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, currentModuleObject, numParams, numAlphas, numNums);
     122         768 :     alphArray.allocate(numAlphas);
     123         768 :     numArray.dimension(numNums, 0.0);
     124         768 :     for (int tabNum = 1; tabNum <= objCount; ++tabNum) {
     125           0 :         state.dataInputProcessing->inputProcessor->getObjectItem(state, currentModuleObject, tabNum, alphArray, numAlphas, numArray, numNums, IOStat);
     126           0 :         if (numAlphas >= 5) {
     127           0 :             annualTables.push_back(AnnualTable(state, alphArray(1), alphArray(2), alphArray(3)));
     128             :             // the remaining fields are repeating in groups of three and need to be added to the data structure
     129           0 :             for (jAlpha = 4; jAlpha <= numAlphas; jAlpha += 2) {
     130           0 :                 curVarMtr = alphArray(jAlpha);
     131           0 :                 if (curVarMtr.empty()) {
     132           0 :                     ShowFatalError(state, "Blank report name in Output:Table:Annual");
     133             :                 }
     134           0 :                 if (jAlpha <= numAlphas) {
     135           0 :                     std::string aggregationString = alphArray(jAlpha + 1);
     136           0 :                     curAgg = stringToAggKind(state, aggregationString);
     137             :                 } else {
     138           0 :                     curAgg = AnnualFieldSet::AggregationKind::sumOrAvg; // if missing aggregation type use SumOrAverage
     139             :                 }
     140           0 :                 indexNums = 1 + (jAlpha - 3) / 2; // compute the corresponding field index in the numArray
     141           0 :                 if (indexNums <= numNums) {
     142           0 :                     curNumDgts = numArray(indexNums);
     143             :                 } else {
     144           0 :                     curNumDgts = 2;
     145             :                 }
     146           0 :                 annualTables.back().addFieldSet(curVarMtr, curAgg, curNumDgts);
     147             :             }
     148           0 :             annualTables.back().setupGathering(state);
     149             :         } else {
     150           0 :             ShowSevereError(state, currentModuleObject + ": Must enter at least the first six fields.");
     151             :         }
     152             :     }
     153             : }
     154             : 
     155           0 : void AnnualTable::addFieldSet(std::string varName, AnnualFieldSet::AggregationKind aggKind, int dgts)
     156             : // Jason Glazer, August 2015
     157             : // This method is used along with the constructor to convert the GetInput for REPORT:TABLE:ANNUAL
     158             : // into the class data.
     159             : {
     160           0 :     m_annualFields.push_back(AnnualFieldSet(varName, aggKind, dgts));
     161           0 :     m_annualFields.back().m_colHead = varName; // use the variable name for the column heading
     162           0 : }
     163             : 
     164           0 : void AnnualTable::addFieldSet(std::string varName, std::string colName, AnnualFieldSet::AggregationKind aggKind, int dgts)
     165             : // Jason Glazer, August 2015
     166             : // This overloaded method allows for a specific column name to be different than the output variable or meter name
     167             : {
     168           0 :     m_annualFields.push_back(AnnualFieldSet(varName, aggKind, dgts));
     169           0 :     m_annualFields.back().m_colHead = colName; // use the user supplied column heading instead of just the variable name
     170           0 : }
     171             : 
     172           0 : void AnnualTable::setupGathering(EnergyPlusData &state)
     173             : // Jason Glazer, August 2015
     174             : // This method is used after GetInput for REPORT:TABLE:ANNUAL to set up how output variables, meters,
     175             : // input fields, and ems variables are gathered.
     176             : {
     177           0 :     int keyCount = 0;
     178           0 :     OutputProcessor::VariableType typeVar = OutputProcessor::VariableType::NotFound;
     179             :     OutputProcessor::StoreType avgSumVar;
     180             :     OutputProcessor::TimeStepType stepTypeVar;
     181           0 :     OutputProcessor::Unit unitsVar = OutputProcessor::Unit::None;
     182           0 :     Array1D_string namesOfKeys;   // keyNames
     183           0 :     Array1D_int indexesForKeyVar; // keyVarIndexes
     184           0 :     std::list<std::string> allKeys;
     185             : 
     186           0 :     std::string filterFieldUpper = m_filter;
     187           0 :     std::transform(filterFieldUpper.begin(), filterFieldUpper.end(), filterFieldUpper.begin(), ::toupper);
     188           0 :     bool useFilter = (m_filter.size() != 0);
     189             : 
     190           0 :     std::vector<AnnualFieldSet>::iterator fldStIt;
     191           0 :     for (fldStIt = m_annualFields.begin(); fldStIt != m_annualFields.end(); ++fldStIt) {
     192           0 :         keyCount = fldStIt->getVariableKeyCountandTypeFromFldSt(state, typeVar, avgSumVar, stepTypeVar, unitsVar);
     193           0 :         fldStIt->getVariableKeysFromFldSt(state, typeVar, keyCount, fldStIt->m_namesOfKeys, fldStIt->m_indexesForKeyVar);
     194           0 :         for (std::string nm : fldStIt->m_namesOfKeys) {
     195           0 :             std::string nmUpper = nm;
     196           0 :             std::transform(nmUpper.begin(), nmUpper.end(), nmUpper.begin(), ::toupper);
     197           0 :             if (!useFilter || nmUpper.find(filterFieldUpper) != std::string::npos) {
     198           0 :                 allKeys.push_back(nm); // create list of all items
     199             :             }
     200             :         }
     201           0 :         fldStIt->m_typeOfVar = typeVar;
     202           0 :         fldStIt->m_varAvgSum = avgSumVar;
     203           0 :         fldStIt->m_varStepType = stepTypeVar;
     204           0 :         fldStIt->m_varUnits = unitsVar;
     205           0 :         fldStIt->m_keyCount = keyCount;
     206             :     }
     207           0 :     allKeys.sort();
     208           0 :     allKeys.unique();                                                        // will now just have a list of the unique keys that is sorted
     209           0 :     std::copy(allKeys.begin(), allKeys.end(), back_inserter(m_objectNames)); // copy list to the object names
     210             :     // size all columns list of cells to be the size of the
     211           0 :     for (fldStIt = m_annualFields.begin(); fldStIt != m_annualFields.end(); ++fldStIt) {
     212           0 :         fldStIt->m_cell.resize(m_objectNames.size());
     213             :     }
     214             :     // for each column (field set) set the rows cell to the output variable index (for variables)
     215             :     int foundKeyIndex;
     216           0 :     int tableRowIndex = 0;
     217           0 :     for (std::vector<std::string>::iterator objNmIt = m_objectNames.begin(); objNmIt != m_objectNames.end(); ++objNmIt) {
     218           0 :         for (fldStIt = m_annualFields.begin(); fldStIt != m_annualFields.end(); ++fldStIt) {
     219           0 :             foundKeyIndex = -1;
     220           0 :             for (std::string::size_type i = 0; i < fldStIt->m_namesOfKeys.size(); i++) {
     221           0 :                 if (fldStIt->m_namesOfKeys[i] == *objNmIt) {
     222           0 :                     foundKeyIndex = i;
     223           0 :                     break;
     224             :                 }
     225             :             }
     226           0 :             if (foundKeyIndex > -1) {
     227           0 :                 fldStIt->m_cell[tableRowIndex].indexesForKeyVar = fldStIt->m_indexesForKeyVar[foundKeyIndex];
     228             :             } else {
     229           0 :                 fldStIt->m_cell[tableRowIndex].indexesForKeyVar = -1; // flag value that cell is not gathered
     230             :             }
     231           0 :             if (fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::maximum ||
     232           0 :                 fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::maximumDuringHoursShown) {
     233           0 :                 fldStIt->m_cell[tableRowIndex].result = -9.9e99;
     234           0 :             } else if (fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::minimum ||
     235           0 :                        fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::minimumDuringHoursShown) {
     236           0 :                 fldStIt->m_cell[tableRowIndex].result = 9.9e99;
     237             :             } else {
     238           0 :                 fldStIt->m_cell[tableRowIndex].result = 0.0;
     239             :             }
     240           0 :             fldStIt->m_cell[tableRowIndex].duration = 0.0;
     241           0 :             fldStIt->m_cell[tableRowIndex].timeStamp = 0;
     242             :         }
     243           0 :         tableRowIndex++;
     244             :     }
     245           0 : }
     246             : 
     247         769 : void checkAggregationOrderForAnnual(EnergyPlusData &state)
     248             : {
     249         771 :     std::vector<AnnualTable>::iterator annualTableIt;
     250         769 :     bool invalidAggregationOrderFound = false;
     251         769 :     auto &annualTables(state.dataOutputReportTabularAnnual->annualTables);
     252         769 :     if (!state.dataGlobal->DoWeathSim) { // if no weather simulation than no reading of MonthlyInput array
     253         767 :         return;
     254             :     }
     255           2 :     for (annualTableIt = annualTables.begin(); annualTableIt != annualTables.end(); ++annualTableIt) {
     256           0 :         if (annualTableIt->invalidAggregationOrder(state)) {
     257           0 :             invalidAggregationOrderFound = true;
     258             :         }
     259             :     }
     260           2 :     if (invalidAggregationOrderFound) {
     261           0 :         ShowFatalError(state, "OutputReportTabularAnnual: Invalid aggregations detected, no simulation performed.");
     262             :     }
     263             : }
     264             : 
     265             : // Generate an error message if an advanced aggregation kind columns don't follow the appropriate column - Glazer 2017
     266           0 : bool AnnualTable::invalidAggregationOrder(EnergyPlusData &state)
     267             : {
     268           0 :     std::vector<AnnualFieldSet>::iterator fldStIt;
     269           0 :     bool foundMinOrMax = false;
     270           0 :     bool foundHourAgg = false;
     271           0 :     bool missingMaxOrMinError = false;
     272           0 :     bool missingHourAggError = false;
     273           0 :     for (fldStIt = m_annualFields.begin(); fldStIt != m_annualFields.end(); ++fldStIt) {
     274           0 :         if ((fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::maximum) ||
     275           0 :             (fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::minimum)) {
     276           0 :             foundMinOrMax = true;
     277           0 :         } else if ((fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::hoursNonZero) ||
     278           0 :                    (fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::hoursZero) ||
     279           0 :                    (fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::hoursPositive) ||
     280           0 :                    (fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::hoursNonPositive) ||
     281           0 :                    (fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::hoursNegative) ||
     282           0 :                    (fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::hoursNonNegative)) {
     283           0 :             foundHourAgg = true;
     284           0 :         } else if (fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::valueWhenMaxMin) {
     285           0 :             if (!foundMinOrMax) {
     286           0 :                 missingMaxOrMinError = true;
     287             :             }
     288           0 :         } else if ((fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::sumOrAverageHoursShown) ||
     289           0 :                    (fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::maximumDuringHoursShown) ||
     290           0 :                    (fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::minimumDuringHoursShown)) {
     291           0 :             if (!foundHourAgg) {
     292           0 :                 missingHourAggError = true;
     293             :             }
     294             :         }
     295             :     }
     296           0 :     if (missingMaxOrMinError) {
     297           0 :         ShowSevereError(state,
     298           0 :                         "The Output:Table:Annual report named=\"" + m_name +
     299             :                             "\" has a valueWhenMaxMin aggregation type for a column without a previous column that uses either the minimum or "
     300             :                             "maximum aggregation types. The report will not be generated.");
     301             :     }
     302           0 :     if (missingHourAggError) {
     303           0 :         ShowSevereError(state,
     304           0 :                         "The Output:Table:Annual report named=\"" + m_name +
     305             :                             "\" has a --DuringHoursShown aggregation type for a column without a previous field that uses one of the Hour-- "
     306             :                             "aggregation types. The report will not be generated.");
     307             :     }
     308           0 :     return (missingHourAggError || missingMaxOrMinError);
     309             : }
     310             : 
     311      161715 : void GatherAnnualResultsForTimeStep(EnergyPlusData &state, OutputProcessor::TimeStepType kindOfTimeStep)
     312             : {
     313             :     // Jason Glazer, August 2015
     314             :     // This function is not part of the class but acts as an interface between procedural code and the class by
     315             :     // gathering data for each of the AnnualTable objects
     316      323430 :     std::vector<AnnualTable>::iterator annualTableIt;
     317      161715 :     auto &annualTables(state.dataOutputReportTabularAnnual->annualTables);
     318      161715 :     for (annualTableIt = annualTables.begin(); annualTableIt != annualTables.end(); ++annualTableIt) {
     319           0 :         annualTableIt->gatherForTimestep(state, kindOfTimeStep);
     320             :     }
     321      161715 : }
     322             : 
     323           0 : void AnnualTable::gatherForTimestep(EnergyPlusData &state, OutputProcessor::TimeStepType kindOfTimeStep)
     324             : {
     325             :     // Jason Glazer, August 2015
     326             :     // For each cell of the table, gather the value as indicated by the type of aggregation
     327             : 
     328             :     int timestepTimeStamp;
     329           0 :     Real64 elapsedTime = AnnualTable::getElapsedTime(state, kindOfTimeStep);
     330           0 :     Real64 secondsInTimeStep = AnnualTable::getSecondsInTimeStep(state, kindOfTimeStep);
     331           0 :     bool activeMinMax = false;
     332           0 :     bool activeHoursShown = false;
     333             :     // if schedule is used and the current value is zero, don't gather values
     334           0 :     if (m_scheduleNum != 0) {
     335           0 :         if (ScheduleManager::GetCurrentScheduleValue(state, m_scheduleNum) == 0.0) {
     336           0 :             return;
     337             :         }
     338             :     }
     339             :     // loop through the fields
     340           0 :     std::vector<AnnualFieldSet>::iterator fldStIt;
     341           0 :     std::vector<AnnualFieldSet>::iterator fldStRemainIt;
     342           0 :     for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
     343           0 :         for (fldStIt = m_annualFields.begin(); fldStIt != m_annualFields.end(); ++fldStIt) {
     344           0 :             OutputProcessor::VariableType curTypeOfVar = fldStIt->m_typeOfVar;
     345           0 :             OutputProcessor::TimeStepType curStepType = fldStIt->m_varStepType;
     346           0 :             if (curStepType == kindOfTimeStep) // this is a much simpler conditional than the code in monthly gathering
     347             :             {
     348           0 :                 int curVarNum = fldStIt->m_cell[row].indexesForKeyVar;
     349           0 :                 if (curVarNum > 0) {
     350           0 :                     Real64 curValue = GetInternalVariableValue(state, curTypeOfVar, curVarNum);
     351             :                     // Get the value from the result array
     352           0 :                     Real64 oldResultValue = fldStIt->m_cell[row].result;
     353             :                     // int oldTimeStamp = fldStIt->m_cell[row].timeStamp;
     354           0 :                     Real64 oldDuration = fldStIt->m_cell[row].duration;
     355             :                     // Zero the revised values (as default if not set later)
     356           0 :                     Real64 newResultValue = 0.0;
     357           0 :                     int newTimeStamp = 0;
     358           0 :                     Real64 newDuration = 0.0;
     359           0 :                     bool activeNewValue = false;
     360             :                     // the current timestamp
     361           0 :                     int minuteCalculated = General::DetermineMinuteForReporting(state, kindOfTimeStep);
     362           0 :                     General::EncodeMonDayHrMin(
     363           0 :                         timestepTimeStamp, state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, minuteCalculated);
     364             :                     // perform the selected aggregation type
     365             :                     // the following types of aggregations are not gathered at this point:
     366             :                     // noAggregation, valueWhenMaxMin, sumOrAverageHoursShown,     maximumDuringHoursShown, minimumDuringHoursShown:
     367           0 :                     switch (fldStIt->m_aggregate) {
     368           0 :                     case AnnualFieldSet::AggregationKind::sumOrAvg:
     369           0 :                         if (fldStIt->m_varAvgSum == OutputProcessor::StoreType::Summed) { // if it is a summed variable
     370           0 :                             newResultValue = oldResultValue + curValue;
     371             :                         } else {
     372           0 :                             newResultValue = oldResultValue + curValue * elapsedTime; // for averaging - weight by elapsed time
     373             :                         }
     374           0 :                         newDuration = oldDuration + elapsedTime;
     375           0 :                         activeNewValue = true;
     376           0 :                         break;
     377           0 :                     case AnnualFieldSet::AggregationKind::maximum:
     378             :                         // per MJW when a summed variable is used divide it by the length of the time step
     379           0 :                         if (fldStIt->m_varAvgSum == OutputProcessor::StoreType::Summed) { // if it is a summed variable
     380           0 :                             curValue /= secondsInTimeStep;
     381             :                         }
     382           0 :                         if (curValue > oldResultValue) {
     383           0 :                             newResultValue = curValue;
     384           0 :                             newTimeStamp = timestepTimeStamp;
     385           0 :                             activeMinMax = true;
     386           0 :                             activeNewValue = true;
     387             :                         } else {
     388           0 :                             activeMinMax = false; // reset this
     389             :                         }
     390           0 :                         break;
     391           0 :                     case AnnualFieldSet::AggregationKind::minimum:
     392             :                         // per MJW when a summed variable is used divide it by the length of the time step
     393           0 :                         if (fldStIt->m_varAvgSum == OutputProcessor::StoreType::Summed) { // if it is a summed variable
     394           0 :                             curValue /= secondsInTimeStep;
     395             :                         }
     396           0 :                         if (curValue < oldResultValue) {
     397           0 :                             newResultValue = curValue;
     398           0 :                             newTimeStamp = timestepTimeStamp;
     399           0 :                             activeMinMax = true;
     400           0 :                             activeNewValue = true;
     401             :                         } else {
     402           0 :                             activeMinMax = false; // reset this
     403             :                         }
     404           0 :                         break;
     405           0 :                     case AnnualFieldSet::AggregationKind::hoursNonZero:
     406           0 :                         if (curValue != 0) {
     407           0 :                             newResultValue = oldResultValue + elapsedTime;
     408           0 :                             activeHoursShown = true;
     409           0 :                             activeNewValue = true;
     410             :                         } else {
     411           0 :                             activeHoursShown = false;
     412             :                         }
     413           0 :                         break;
     414           0 :                     case AnnualFieldSet::AggregationKind::hoursZero:
     415           0 :                         if (curValue == 0) {
     416           0 :                             newResultValue = oldResultValue + elapsedTime;
     417           0 :                             activeHoursShown = true;
     418           0 :                             activeNewValue = true;
     419             :                         } else {
     420           0 :                             activeHoursShown = false;
     421             :                         }
     422           0 :                         break;
     423           0 :                     case AnnualFieldSet::AggregationKind::hoursPositive:
     424           0 :                         if (curValue > 0) {
     425           0 :                             newResultValue = oldResultValue + elapsedTime;
     426           0 :                             activeHoursShown = true;
     427           0 :                             activeNewValue = true;
     428             :                         } else {
     429           0 :                             activeHoursShown = false;
     430             :                         }
     431           0 :                         break;
     432           0 :                     case AnnualFieldSet::AggregationKind::hoursNonPositive:
     433           0 :                         if (curValue <= 0) {
     434           0 :                             newResultValue = oldResultValue + elapsedTime;
     435           0 :                             activeHoursShown = true;
     436           0 :                             activeNewValue = true;
     437             :                         } else {
     438           0 :                             activeHoursShown = false;
     439             :                         }
     440           0 :                         break;
     441           0 :                     case AnnualFieldSet::AggregationKind::hoursNegative:
     442           0 :                         if (curValue < 0) {
     443           0 :                             newResultValue = oldResultValue + elapsedTime;
     444           0 :                             activeHoursShown = true;
     445           0 :                             activeNewValue = true;
     446             :                         } else {
     447           0 :                             activeHoursShown = false;
     448             :                         }
     449           0 :                         break;
     450           0 :                     case AnnualFieldSet::AggregationKind::hoursNonNegative:
     451           0 :                         if (curValue >= 0) {
     452           0 :                             newResultValue = oldResultValue + elapsedTime;
     453           0 :                             activeHoursShown = true;
     454           0 :                             activeNewValue = true;
     455             :                         } else {
     456           0 :                             activeHoursShown = false;
     457             :                         }
     458           0 :                         break;
     459           0 :                     case AnnualFieldSet::AggregationKind::hoursInTenPercentBins:
     460             :                     case AnnualFieldSet::AggregationKind::hoursInTenBinsMinToMax:
     461             :                     case AnnualFieldSet::AggregationKind::hoursInTenBinsZeroToMax:
     462             :                     case AnnualFieldSet::AggregationKind::hoursInTenBinsMinToZero:
     463             :                     case AnnualFieldSet::AggregationKind::hoursInTenBinsPlusMinusTwoStdDev:
     464             :                     case AnnualFieldSet::AggregationKind::hoursInTenBinsPlusMinusThreeStdDev:
     465             :                         //  for all of the binning options add the value to the deferred
     466           0 :                         if (fldStIt->m_varAvgSum == OutputProcessor::StoreType::Summed) {                  // if it is a summed variable
     467           0 :                             fldStIt->m_cell[row].deferredResults.push_back(curValue /= secondsInTimeStep); // divide by time just like max and min
     468             :                         } else {
     469           0 :                             fldStIt->m_cell[row].deferredResults.push_back(curValue);
     470             :                         }
     471           0 :                         fldStIt->m_cell[row].deferredElapsed.push_back(elapsedTime); // save the amount of time for this particular value
     472           0 :                         newDuration = oldDuration + elapsedTime;
     473           0 :                         break;
     474           0 :                     case AnnualFieldSet::AggregationKind::noAggregation:
     475             :                     case AnnualFieldSet::AggregationKind::valueWhenMaxMin:
     476             :                     case AnnualFieldSet::AggregationKind::sumOrAverageHoursShown:
     477             :                     case AnnualFieldSet::AggregationKind::maximumDuringHoursShown:
     478             :                     case AnnualFieldSet::AggregationKind::minimumDuringHoursShown:
     479             :                         // do nothing
     480           0 :                         break;
     481             :                     } // end switch fldStIt->m_aggregate
     482             : 
     483             :                     // if the new value has been set then set the monthly values to the
     484             :                     // new columns. This skips the aggregation types that don't even get
     485             :                     // triggered now such as valueWhenMinMax and all the agg*HoursShown
     486           0 :                     if (activeNewValue) {
     487           0 :                         fldStIt->m_cell[row].result = newResultValue;
     488           0 :                         fldStIt->m_cell[row].timeStamp = newTimeStamp;
     489           0 :                         fldStIt->m_cell[row].duration = newDuration;
     490             :                     }
     491             :                     // if a minimum or maximum value was set this timeStep then
     492             :                     // scan the remaining columns of the table looking for values
     493             :                     // that are aggregation type "ValueWhenMaxMin" and set their values
     494             :                     // if another minimum or maximum column is found then end
     495             :                     // the scan (it will be taken care of when that column is done)
     496           0 :                     if (activeMinMax) {
     497           0 :                         for (fldStRemainIt = fldStIt + 1; fldStRemainIt != m_annualFields.end(); ++fldStRemainIt) {
     498           0 :                             if (fldStRemainIt->m_aggregate == AnnualFieldSet::AggregationKind::maximum ||
     499           0 :                                 fldStRemainIt->m_aggregate == AnnualFieldSet::AggregationKind::minimum) {
     500             :                                 // end scanning since these might reset
     501           0 :                                 break; // for fldStRemainIt
     502           0 :                             } else if (fldStRemainIt->m_aggregate == AnnualFieldSet::AggregationKind::valueWhenMaxMin) {
     503             :                                 // this case is when the value should be set
     504           0 :                                 OutputProcessor::VariableType scanTypeOfVar = fldStRemainIt->m_typeOfVar;
     505             :                                 // int scanStepType = fldStRemainIt->m_varStepType;
     506           0 :                                 int scanVarNum = fldStRemainIt->m_cell[row].indexesForKeyVar;
     507           0 :                                 if (scanVarNum > 0) {
     508           0 :                                     Real64 scanValue = GetInternalVariableValue(state, scanTypeOfVar, scanVarNum);
     509             :                                     // When a summed variable is used divide it by the length of the time step
     510           0 :                                     if (fldStRemainIt->m_varAvgSum == OutputProcessor::StoreType::Summed) { // if it is a summed variable
     511           0 :                                         scanValue /= secondsInTimeStep;
     512             :                                     }
     513           0 :                                     fldStRemainIt->m_cell[row].result = scanValue;
     514             :                                 }
     515             :                             } else {
     516             :                                 // do nothing
     517             :                             }
     518             :                         }
     519             :                     }
     520             :                     // If the hours variable is active then scan through the rest of the variables
     521             :                     // and accumulate
     522           0 :                     if (activeHoursShown) {
     523           0 :                         for (fldStRemainIt = fldStIt + 1; fldStRemainIt != m_annualFields.end(); ++fldStRemainIt) {
     524           0 :                             OutputProcessor::VariableType scanTypeOfVar = fldStRemainIt->m_typeOfVar;
     525             :                             // int scanStepType = fldStRemainIt->m_varStepType;
     526           0 :                             int scanVarNum = fldStRemainIt->m_cell[row].indexesForKeyVar;
     527           0 :                             Real64 oldScanValue = fldStRemainIt->m_cell[row].result;
     528           0 :                             if (scanVarNum > 0) {
     529           0 :                                 Real64 scanValue = GetInternalVariableValue(state, scanTypeOfVar, scanVarNum);
     530           0 :                                 if (fldStRemainIt->m_aggregate == AnnualFieldSet::AggregationKind::hoursZero ||
     531           0 :                                     fldStRemainIt->m_aggregate == AnnualFieldSet::AggregationKind::hoursNonZero ||
     532           0 :                                     fldStRemainIt->m_aggregate == AnnualFieldSet::AggregationKind::hoursPositive ||
     533           0 :                                     fldStRemainIt->m_aggregate == AnnualFieldSet::AggregationKind::hoursNonPositive ||
     534           0 :                                     fldStRemainIt->m_aggregate == AnnualFieldSet::AggregationKind::hoursNegative ||
     535           0 :                                     fldStRemainIt->m_aggregate == AnnualFieldSet::AggregationKind::hoursNonNegative) {
     536             :                                     // end scanning since these might reset
     537           0 :                                     break; // for fldStRemainIt
     538           0 :                                 } else if (fldStRemainIt->m_aggregate == AnnualFieldSet::AggregationKind::sumOrAverageHoursShown) {
     539           0 :                                     if (fldStIt->m_varAvgSum == OutputProcessor::StoreType::Summed) { // if it is a summed variable
     540           0 :                                         fldStRemainIt->m_cell[row].result = oldScanValue + scanValue;
     541             :                                     } else {
     542           0 :                                         fldStRemainIt->m_cell[row].result =
     543           0 :                                             oldScanValue + scanValue * elapsedTime; // for averaging - weight by elapsed time
     544             :                                     }
     545           0 :                                     fldStRemainIt->m_cell[row].duration += elapsedTime;
     546           0 :                                 } else if (fldStRemainIt->m_aggregate == AnnualFieldSet::AggregationKind::minimumDuringHoursShown) {
     547           0 :                                     if (fldStRemainIt->m_varAvgSum == OutputProcessor::StoreType::Summed) { // if it is a summed variable
     548           0 :                                         scanValue /= secondsInTimeStep;
     549             :                                     }
     550           0 :                                     if (scanValue < oldScanValue) {
     551           0 :                                         fldStRemainIt->m_cell[row].result = scanValue;
     552           0 :                                         fldStRemainIt->m_cell[row].timeStamp = timestepTimeStamp;
     553             :                                     }
     554           0 :                                 } else if (fldStRemainIt->m_aggregate == AnnualFieldSet::AggregationKind::maximumDuringHoursShown) {
     555           0 :                                     if (fldStRemainIt->m_varAvgSum == OutputProcessor::StoreType::Summed) { // if it is a summed variable
     556           0 :                                         scanValue /= secondsInTimeStep;
     557             :                                     }
     558           0 :                                     if (scanValue > oldScanValue) {
     559           0 :                                         fldStRemainIt->m_cell[row].result = scanValue;
     560           0 :                                         fldStRemainIt->m_cell[row].timeStamp = timestepTimeStamp;
     561             :                                     }
     562             :                                 } else {
     563             :                                     // do nothing
     564             :                                 }
     565             :                             }
     566           0 :                             activeHoursShown = false; // fixed CR8317
     567             :                         }
     568             :                     }
     569             :                 }
     570             :             }
     571             :         }
     572             :     }
     573             : }
     574             : 
     575           0 : void ResetAnnualGathering(EnergyPlusData &state)
     576             : {
     577             :     // Jason Glazer, October 2015
     578             :     // This function is not part of the class but acts as an interface between procedural code and the class by
     579             :     // resetting data for each of the AnnualTable objects
     580           0 :     std::vector<AnnualTable>::iterator annualTableIt;
     581           0 :     auto &annualTables(state.dataOutputReportTabularAnnual->annualTables);
     582           0 :     for (annualTableIt = annualTables.begin(); annualTableIt != annualTables.end(); ++annualTableIt) {
     583           0 :         annualTableIt->resetGathering();
     584             :     }
     585           0 : }
     586             : 
     587           0 : void AnnualTable::resetGathering()
     588             : {
     589           0 :     std::vector<AnnualFieldSet>::iterator fldStIt;
     590           0 :     for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
     591           0 :         for (fldStIt = m_annualFields.begin(); fldStIt != m_annualFields.end(); ++fldStIt) {
     592           0 :             if (fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::maximum ||
     593           0 :                 fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::maximumDuringHoursShown) {
     594           0 :                 fldStIt->m_cell[row].result = -9.9e99;
     595           0 :             } else if (fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::minimum ||
     596           0 :                        fldStIt->m_aggregate == AnnualFieldSet::AggregationKind::minimumDuringHoursShown) {
     597           0 :                 fldStIt->m_cell[row].result = 9.9e99;
     598             :             } else {
     599           0 :                 fldStIt->m_cell[row].result = 0.0;
     600             :             }
     601           0 :             fldStIt->m_cell[row].duration = 0.0;
     602           0 :             fldStIt->m_cell[row].timeStamp = 0;
     603             :             // if any defered results
     604           0 :             fldStIt->m_cell[row].deferredResults.clear();
     605           0 :             fldStIt->m_cell[row].deferredElapsed.clear();
     606             :         }
     607             :     }
     608           0 : }
     609             : 
     610           0 : Real64 AnnualTable::getElapsedTime(EnergyPlusData &state, OutputProcessor::TimeStepType kindOfTimeStep)
     611             : {
     612             :     Real64 elapsedTime;
     613           0 :     if (kindOfTimeStep == OutputProcessor::TimeStepType::Zone) {
     614           0 :         elapsedTime = state.dataHVACGlobal->TimeStepSys;
     615             :     } else {
     616           0 :         elapsedTime = state.dataGlobal->TimeStepZone;
     617             :     }
     618           0 :     return elapsedTime;
     619             : }
     620             : 
     621           0 : Real64 AnnualTable::getSecondsInTimeStep(EnergyPlusData &state, OutputProcessor::TimeStepType kindOfTimeStep)
     622             : {
     623             :     Real64 secondsInTimeStep;
     624           0 :     if (kindOfTimeStep == OutputProcessor::TimeStepType::Zone) {
     625           0 :         secondsInTimeStep = state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
     626             :     } else {
     627           0 :         secondsInTimeStep = state.dataGlobal->TimeStepZoneSec;
     628             :     }
     629           0 :     return secondsInTimeStep;
     630             : }
     631             : 
     632           2 : void WriteAnnualTables(EnergyPlusData &state)
     633             : {
     634           2 :     auto &annualTables(state.dataOutputReportTabularAnnual->annualTables);
     635           4 :     for (int iUnitSystem = 0; iUnitSystem <= 1; iUnitSystem++) {
     636           4 :         OutputReportTabular::UnitsStyle unitsStyle_cur = state.dataOutRptTab->unitsStyle;
     637           4 :         bool produceTabular = true;
     638           4 :         bool produceSQLite = false;
     639           8 :         if (produceDualUnitsFlags(
     640           8 :                 iUnitSystem, state.dataOutRptTab->unitsStyle, state.dataOutRptTab->unitsStyle_SQLite, unitsStyle_cur, produceTabular, produceSQLite))
     641           2 :             break;
     642             : 
     643             :         // Jason Glazer, August 2015
     644             :         // This function is not part of the class but acts as an interface between procedural code and the class by
     645             :         // invoking the writeTable member function for each of the AnnualTable objects
     646           4 :         std::vector<AnnualTable>::iterator annualTableIt;
     647           2 :         for (annualTableIt = annualTables.begin(); annualTableIt != annualTables.end(); ++annualTableIt) {
     648           0 :             annualTableIt->writeTable(state, unitsStyle_cur, produceTabular, produceSQLite);
     649             :         }
     650             :     }
     651           2 : }
     652             : 
     653           0 : void AnnualTable::writeTable(EnergyPlusData &state, OutputReportTabular::UnitsStyle unitsStyle, bool produceTabular_para, bool produceSQLite_para)
     654             : {
     655           0 :     Array1D_string columnHead;
     656           0 :     Array1D_int columnWidth;
     657           0 :     Array1D_string rowHead;
     658           0 :     Array2D_string tableBody;
     659           0 :     Real64 veryLarge = 1.0E280;
     660           0 :     Real64 verySmall = -1.0E280;
     661           0 :     std::vector<std::string> aggString;
     662           0 :     std::string energyUnitsString;
     663           0 :     std::string varNameWithUnits;
     664             :     int indexUnitConv;
     665             :     Real64 curVal;
     666           0 :     std::string curUnits;
     667             :     Real64 curConversionFactor;
     668             :     Real64 curConversionOffset;
     669             :     Real64 minVal;
     670             :     Real64 maxVal;
     671             :     Real64 sumVal;
     672             :     Real64 sumDuration;
     673           0 :     bool createBinRangeTable = false;
     674             : 
     675             :     static Real64 const storedMaxVal(std::numeric_limits<Real64>::max());
     676             :     static Real64 const storedMinVal(std::numeric_limits<Real64>::lowest());
     677             : 
     678           0 :     aggString = setupAggString();
     679           0 :     Real64 energyUnitsConversionFactor = AnnualTable::setEnergyUnitStringAndFactor(unitsStyle, energyUnitsString);
     680             : 
     681             :     // Compute the columns related to the binning schemes
     682           0 :     computeBinColumns(state, unitsStyle);
     683             : 
     684             :     // Use title case names of variables if available for column headers
     685           0 :     columnHeadersToTitleCase(state);
     686             : 
     687             :     // first loop through and count how many 'columns' are defined
     688             :     // since max and min actually define two columns (the value
     689             :     // and the timestamp).
     690           0 :     int columnCount = 0;
     691           0 :     std::vector<AnnualFieldSet>::iterator fldStIt;
     692           0 :     for (fldStIt = m_annualFields.begin(); fldStIt != m_annualFields.end(); ++fldStIt) {
     693           0 :         columnCount += columnCountForAggregation(fldStIt->m_aggregate);
     694             :     }
     695           0 :     columnHead.allocate(columnCount);
     696           0 :     columnWidth.dimension(columnCount);
     697           0 :     columnWidth = 14;                        // array assignment - same for all columns
     698           0 :     int rowCount = m_objectNames.size() + 4; // add blank, sum/avg, min, max rows.
     699           0 :     int rowSumAvg = m_objectNames.size() + 2;
     700           0 :     int rowMin = m_objectNames.size() + 3;
     701           0 :     int rowMax = m_objectNames.size() + 4;
     702             : 
     703           0 :     rowHead.allocate(rowCount);
     704           0 :     for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
     705           0 :         rowHead(row + 1) = m_objectNames[row];
     706             :     }
     707           0 :     rowHead(rowSumAvg) = "Annual Sum or Average";
     708           0 :     rowHead(rowMin) = "Minimum of Rows";
     709           0 :     rowHead(rowMax) = "Maximum of Rows";
     710             : 
     711           0 :     tableBody.allocate(columnCount, rowCount);
     712           0 :     tableBody = ""; // set entire table to blank as default
     713           0 :     int columnRecount = 0;
     714           0 :     for (fldStIt = m_annualFields.begin(); fldStIt != m_annualFields.end(); ++fldStIt) {
     715           0 :         std::string curAggString = aggString[(int)fldStIt->m_aggregate];
     716           0 :         if (curAggString.size() > 0) {
     717           0 :             curAggString = " {" + trim(curAggString) + '}';
     718             :         }
     719             :         // do the unit conversions
     720           0 :         if (unitsStyle == OutputReportTabular::UnitsStyle::InchPound) {
     721           0 :             varNameWithUnits = fldStIt->m_variMeter + unitEnumToStringBrackets(fldStIt->m_varUnits);
     722           0 :             OutputReportTabular::LookupSItoIP(state, varNameWithUnits, indexUnitConv, curUnits);
     723           0 :             OutputReportTabular::GetUnitConversion(state, indexUnitConv, curConversionFactor, curConversionOffset, curUnits);
     724             :         } else { // just do the Joule conversion
     725             :             // if units is in Joules, convert if specified
     726           0 :             if (fldStIt->m_varUnits == OutputProcessor::Unit::J) {
     727           0 :                 curUnits = energyUnitsString;
     728           0 :                 curConversionFactor = energyUnitsConversionFactor;
     729           0 :                 curConversionOffset = 0.0;
     730             :             } else { // if not joules don't perform conversion
     731           0 :                 curUnits = unitEnumToString(fldStIt->m_varUnits);
     732           0 :                 curConversionFactor = 1.0;
     733           0 :                 curConversionOffset = 0.0;
     734             :             }
     735             :         }
     736           0 :         int curAgg = fldStIt->m_aggregate;
     737           0 :         columnRecount += columnCountForAggregation(fldStIt->m_aggregate);
     738           0 :         if ((curAgg == AnnualFieldSet::AggregationKind::sumOrAvg) || (curAgg == AnnualFieldSet::AggregationKind::sumOrAverageHoursShown)) {
     739             :             // put in the name of the variable for the column
     740           0 :             columnHead(columnRecount) = fldStIt->m_colHead + curAggString + " [" + curUnits + ']';
     741           0 :             sumVal = 0.0;
     742           0 :             sumDuration = 0.0;
     743           0 :             minVal = storedMaxVal;
     744           0 :             maxVal = storedMinVal;
     745             : 
     746           0 :             for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
     747           0 :                 if (fldStIt->m_cell[row].indexesForKeyVar >= 0) {
     748           0 :                     if (fldStIt->m_varAvgSum == OutputProcessor::StoreType::Averaged) { // if it is a average variable divide by duration
     749           0 :                         if (fldStIt->m_cell[row].duration != 0.0) {
     750           0 :                             curVal = ((fldStIt->m_cell[row].result / fldStIt->m_cell[row].duration) * curConversionFactor) + curConversionOffset;
     751             :                         } else {
     752           0 :                             curVal = 0.0;
     753             :                         }
     754           0 :                         sumVal += (fldStIt->m_cell[row].result * curConversionFactor) + curConversionOffset;
     755           0 :                         sumDuration += fldStIt->m_cell[row].duration;
     756             :                     } else {
     757           0 :                         curVal = (fldStIt->m_cell[row].result * curConversionFactor) + curConversionOffset;
     758           0 :                         sumVal += curVal;
     759             :                     }
     760           0 :                     tableBody(columnRecount, row + 1) = OutputReportTabular::RealToStr(curVal, fldStIt->m_showDigits);
     761           0 :                     if (curVal > maxVal) maxVal = curVal;
     762           0 :                     if (curVal < minVal) minVal = curVal;
     763             :                 } else {
     764           0 :                     tableBody(columnRecount, row + 1) = "-";
     765             :                 }
     766             : 
     767             :             } // row
     768             :             // add the summary to bottom
     769           0 :             if (fldStIt->m_varAvgSum == OutputProcessor::StoreType::Averaged) { // if it is a average variable divide by duration
     770           0 :                 if (sumDuration > 0) {
     771           0 :                     tableBody(columnRecount, rowSumAvg) = OutputReportTabular::RealToStr(sumVal / sumDuration, fldStIt->m_showDigits);
     772             :                 } else {
     773           0 :                     tableBody(columnRecount, rowSumAvg) = "";
     774             :                 }
     775             :             } else {
     776           0 :                 tableBody(columnRecount, rowSumAvg) = OutputReportTabular::RealToStr(sumVal, fldStIt->m_showDigits);
     777             :             }
     778           0 :             if (minVal != storedMaxVal) {
     779           0 :                 tableBody(columnRecount, rowMax) = OutputReportTabular::RealToStr(minVal, fldStIt->m_showDigits);
     780             :             }
     781           0 :             if (maxVal != storedMinVal) {
     782           0 :                 tableBody(columnRecount, rowMin) = OutputReportTabular::RealToStr(maxVal, fldStIt->m_showDigits);
     783           0 :             }
     784           0 :         } else if ((curAgg == AnnualFieldSet::AggregationKind::hoursZero) || (curAgg == AnnualFieldSet::AggregationKind::hoursNonZero) ||
     785           0 :                    (curAgg == AnnualFieldSet::AggregationKind::hoursPositive) || (curAgg == AnnualFieldSet::AggregationKind::hoursNonPositive) ||
     786           0 :                    (curAgg == AnnualFieldSet::AggregationKind::hoursNegative) || (curAgg == AnnualFieldSet::AggregationKind::hoursNonNegative)) {
     787             :             // put in the name of the variable for the column
     788           0 :             columnHead(columnRecount) = fldStIt->m_colHead + curAggString + " [HOURS]";
     789           0 :             sumVal = 0.0;
     790           0 :             minVal = storedMaxVal;
     791           0 :             maxVal = storedMinVal;
     792           0 :             for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
     793           0 :                 curVal = fldStIt->m_cell[row].result;
     794           0 :                 curVal = curVal * curConversionFactor + curConversionOffset;
     795           0 :                 tableBody(columnRecount, row + 1) = OutputReportTabular::RealToStr(curVal, fldStIt->m_showDigits);
     796           0 :                 sumVal += curVal;
     797           0 :                 if (curVal > maxVal) maxVal = curVal;
     798           0 :                 if (curVal < minVal) minVal = curVal;
     799             :             } // row
     800             :             // add the summary to bottom
     801           0 :             tableBody(columnRecount, rowSumAvg) = OutputReportTabular::RealToStr(sumVal, fldStIt->m_showDigits);
     802           0 :             if (minVal != storedMaxVal) {
     803           0 :                 tableBody(columnRecount, rowMax) = OutputReportTabular::RealToStr(minVal, fldStIt->m_showDigits);
     804             :             }
     805           0 :             if (maxVal != storedMinVal) {
     806           0 :                 tableBody(columnRecount, rowMin) = OutputReportTabular::RealToStr(maxVal, fldStIt->m_showDigits);
     807           0 :             }
     808           0 :         } else if (curAgg == AnnualFieldSet::AggregationKind::valueWhenMaxMin) {
     809           0 :             if (fldStIt->m_varAvgSum == OutputProcessor::StoreType::Summed) {
     810           0 :                 curUnits += "/s";
     811             :             }
     812           0 :             fixUnitsPerSecond(curUnits, curConversionFactor);
     813           0 :             columnHead(columnRecount) = fldStIt->m_colHead + curAggString + " [" + curUnits + ']';
     814           0 :             minVal = storedMaxVal;
     815           0 :             maxVal = storedMinVal;
     816           0 :             for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
     817           0 :                 curVal = fldStIt->m_cell[row].result;
     818           0 :                 curVal = curVal * curConversionFactor + curConversionOffset;
     819           0 :                 tableBody(columnRecount, row + 1) = OutputReportTabular::RealToStr(curVal, fldStIt->m_showDigits);
     820           0 :                 if (curVal > maxVal) maxVal = curVal;
     821           0 :                 if (curVal < minVal) minVal = curVal;
     822             :             } // row
     823             :             // add the summary to bottom
     824           0 :             if (minVal != storedMaxVal) {
     825           0 :                 tableBody(columnRecount, rowMin) = OutputReportTabular::RealToStr(minVal, fldStIt->m_showDigits);
     826             :             }
     827           0 :             if (maxVal != storedMinVal) {
     828           0 :                 tableBody(columnRecount, rowMax) = OutputReportTabular::RealToStr(maxVal, fldStIt->m_showDigits);
     829             :             }
     830           0 :         } else if ((curAgg == AnnualFieldSet::AggregationKind::maximum) || (curAgg == AnnualFieldSet::AggregationKind::minimum) ||
     831           0 :                    (curAgg == AnnualFieldSet::AggregationKind::maximumDuringHoursShown) ||
     832             :                    (curAgg == AnnualFieldSet::AggregationKind::minimumDuringHoursShown)) {
     833             :             // put in the name of the variable for the column
     834           0 :             if (fldStIt->m_varAvgSum == OutputProcessor::StoreType::Summed) { // if it is a summed variable
     835           0 :                 curUnits += "/s";
     836             :             }
     837           0 :             fixUnitsPerSecond(curUnits, curConversionFactor);
     838           0 :             columnHead(columnRecount - 1) = fldStIt->m_colHead + curAggString + " [" + curUnits + ']';
     839           0 :             columnHead(columnRecount) = fldStIt->m_colHead + " {TIMESTAMP}";
     840           0 :             minVal = storedMaxVal;
     841           0 :             maxVal = storedMinVal;
     842           0 :             for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
     843           0 :                 curVal = fldStIt->m_cell[row].result;
     844             :                 // CR7788 the conversion factors were causing an overflow for the InchPound case since the
     845             :                 // value was very small
     846             :                 // restructured the following lines to hide showing HUGE and -HUGE values in output table CR8154 Glazer
     847           0 :                 if ((curVal < veryLarge) && (curVal > verySmall)) {
     848           0 :                     curVal = curVal * curConversionFactor + curConversionOffset;
     849           0 :                     if (curVal > maxVal) maxVal = curVal;
     850           0 :                     if (curVal < minVal) minVal = curVal;
     851           0 :                     if (curVal < veryLarge && curVal > verySmall) {
     852           0 :                         tableBody(columnRecount - 1, row + 1) = OutputReportTabular::RealToStr(curVal, fldStIt->m_showDigits);
     853             :                     } else {
     854           0 :                         tableBody(columnRecount - 1, row + 1) = "-";
     855             :                     }
     856           0 :                     tableBody(columnRecount, row + 1) = OutputReportTabular::DateToString(fldStIt->m_cell[row].timeStamp);
     857             :                 } else {
     858           0 :                     tableBody(columnRecount - 1, row + 1) = "-";
     859           0 :                     tableBody(columnRecount, row + 1) = "-";
     860             :                 }
     861             :             } // row
     862             :             // add the summary to bottom
     863             :             // Don't include if the original min and max values are still present
     864           0 :             if (minVal < veryLarge) {
     865           0 :                 tableBody(columnRecount - 1, rowMin) = OutputReportTabular::RealToStr(minVal, fldStIt->m_showDigits);
     866             :             } else {
     867           0 :                 tableBody(columnRecount - 1, rowMin) = "-";
     868             :             }
     869           0 :             if (maxVal > verySmall) {
     870           0 :                 tableBody(columnRecount - 1, rowMax) = OutputReportTabular::RealToStr(maxVal, fldStIt->m_showDigits);
     871             :             } else {
     872           0 :                 tableBody(columnRecount - 1, rowMax) = "-";
     873           0 :             }
     874           0 :         } else if (curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsMinToMax) {
     875             :             // put in the name of the variable for the column
     876           0 :             if (fldStIt->m_varAvgSum == OutputProcessor::StoreType::Summed) { // if it is a summed variable
     877           0 :                 curUnits += "/s";
     878             :             }
     879           0 :             fixUnitsPerSecond(curUnits, curConversionFactor);
     880           0 :             for (int iBin = 0; iBin != 10; iBin++) {
     881           0 :                 char binIndicator = iBin + 65;
     882           0 :                 columnHead(columnRecount - 9 + iBin) = fldStIt->m_colHead + curAggString + " BIN " + binIndicator;
     883           0 :                 for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
     884           0 :                     tableBody(columnRecount - 9 + iBin, row + 1) =
     885           0 :                         OutputReportTabular::RealToStr(fldStIt->m_cell[row].m_timeInBin[iBin], fldStIt->m_showDigits);
     886             :                 }
     887           0 :                 tableBody(columnRecount - 9 + iBin, rowSumAvg) =
     888           0 :                     OutputReportTabular::RealToStr(fldStIt->m_timeInBinTotal[iBin], fldStIt->m_showDigits);
     889             :             }
     890           0 :             createBinRangeTable = true;
     891           0 :         } else if (curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsZeroToMax) {
     892             :             // put in the name of the variable for the column
     893           0 :             if (fldStIt->m_varAvgSum == OutputProcessor::StoreType::Summed) { // if it is a summed variable
     894           0 :                 curUnits += "/s";
     895             :             }
     896           0 :             fixUnitsPerSecond(curUnits, curConversionFactor);
     897           0 :             for (int iBin = 0; iBin != 10; iBin++) {
     898           0 :                 char binIndicator = iBin + 65;
     899           0 :                 columnHead(columnRecount - 9 + iBin) = fldStIt->m_colHead + curAggString + " BIN " + binIndicator;
     900           0 :                 for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
     901           0 :                     tableBody(columnRecount - 9 + iBin, row + 1) =
     902           0 :                         OutputReportTabular::RealToStr(fldStIt->m_cell[row].m_timeInBin[iBin], fldStIt->m_showDigits);
     903             :                 }
     904           0 :                 tableBody(columnRecount - 9 + iBin, rowSumAvg) =
     905           0 :                     OutputReportTabular::RealToStr(fldStIt->m_timeInBinTotal[iBin], fldStIt->m_showDigits);
     906             :             }
     907           0 :             columnHead(columnRecount - 10) = fldStIt->m_colHead + curAggString + " LESS THAN BIN A";
     908           0 :             for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
     909           0 :                 tableBody(columnRecount - 10, row + 1) =
     910           0 :                     OutputReportTabular::RealToStr(fldStIt->m_cell[row].m_timeBelowBottomBin, fldStIt->m_showDigits);
     911             :             }
     912           0 :             tableBody(columnRecount - 10, rowSumAvg) = OutputReportTabular::RealToStr(fldStIt->m_timeBelowBottomBinTotal, fldStIt->m_showDigits);
     913           0 :             createBinRangeTable = true;
     914           0 :         } else if (curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsMinToZero) {
     915             :             // put in the name of the variable for the column
     916           0 :             if (fldStIt->m_varAvgSum == OutputProcessor::StoreType::Summed) { // if it is a summed variable
     917           0 :                 curUnits += "/s";
     918             :             }
     919           0 :             fixUnitsPerSecond(curUnits, curConversionFactor);
     920           0 :             for (int iBin = 0; iBin != 10; iBin++) {
     921           0 :                 char binIndicator = iBin + 65;
     922           0 :                 columnHead(columnRecount - 10 + iBin) = fldStIt->m_colHead + curAggString + " BIN " + binIndicator;
     923           0 :                 for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
     924           0 :                     tableBody(columnRecount - 10 + iBin, row + 1) =
     925           0 :                         OutputReportTabular::RealToStr(fldStIt->m_cell[row].m_timeInBin[iBin], fldStIt->m_showDigits);
     926             :                 }
     927           0 :                 tableBody(columnRecount - 10 + iBin, rowSumAvg) =
     928           0 :                     OutputReportTabular::RealToStr(fldStIt->m_timeInBinTotal[iBin], fldStIt->m_showDigits);
     929             :             }
     930           0 :             columnHead(columnRecount) = fldStIt->m_colHead + curAggString + " MORE THAN BIN J";
     931           0 :             for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
     932           0 :                 tableBody(columnRecount, row + 1) = OutputReportTabular::RealToStr(fldStIt->m_cell[row].m_timeAboveTopBin, fldStIt->m_showDigits);
     933             :             }
     934           0 :             tableBody(columnRecount, rowSumAvg) = OutputReportTabular::RealToStr(fldStIt->m_timeAboveTopBinTotal, fldStIt->m_showDigits);
     935           0 :             createBinRangeTable = true;
     936             :         } else if (curAgg == AnnualFieldSet::AggregationKind::hoursInTenPercentBins ||
     937             :                    curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsPlusMinusTwoStdDev ||
     938             :                    curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsPlusMinusThreeStdDev) {
     939             :         }
     940             :     } // fldStIt
     941           0 :     if (produceTabular_para) {
     942           0 :         OutputReportTabular::WriteReportHeaders(state, m_name, "Entire Facility", OutputProcessor::StoreType::Averaged);
     943           0 :         OutputReportTabular::WriteSubtitle(state, "Custom Annual Report");
     944           0 :         OutputReportTabular::WriteTable(state, tableBody, rowHead, columnHead, columnWidth, true); // transpose annual XML tables.
     945             :     }
     946           0 :     if (produceSQLite_para) {
     947           0 :         if (state.dataSQLiteProcedures->sqlite) {
     948           0 :             state.dataSQLiteProcedures->sqlite->createSQLiteTabularDataRecords(
     949             :                 tableBody, rowHead, columnHead, m_name, "Entire Facility", "Custom Annual Report");
     950             :         }
     951             :     }
     952             :     // for the new binning aggregation types create a second table of the bin ranges
     953           0 :     if (createBinRangeTable) {
     954           0 :         Array1D_string colHeadRange;
     955           0 :         Array1D_int colWidthRange;
     956           0 :         Array1D_string rowHeadRange;
     957           0 :         Array2D_string tableBodyRange;
     958           0 :         colHeadRange.allocate(10);
     959           0 :         colWidthRange.allocate(10);
     960           0 :         colWidthRange = 14; // array assignment - same for all columns
     961           0 :         rowHeadRange.allocate(2);
     962           0 :         rowHeadRange(1) = ">=";
     963           0 :         rowHeadRange(2) = "<";
     964           0 :         tableBodyRange.allocate(10, 2);
     965           0 :         for (fldStIt = m_annualFields.begin(); fldStIt != m_annualFields.end(); ++fldStIt) {
     966           0 :             int curAgg = fldStIt->m_aggregate;
     967           0 :             if ((curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsMinToMax) ||
     968           0 :                 (curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsZeroToMax) ||
     969             :                 (curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsMinToZero)) {
     970           0 :                 tableBodyRange = ""; // set entire table to blank as default
     971           0 :                 Real64 binBottom = fldStIt->m_bottomBinValue;
     972           0 :                 Real64 binTop = fldStIt->m_topBinValue;
     973           0 :                 Real64 numBins = 10.;
     974           0 :                 Real64 intervalSize = (binTop - binBottom) / numBins;
     975             : 
     976             :                 // could not get the following to work using
     977           0 :                 colHeadRange(1) = "BIN A";
     978           0 :                 colHeadRange(2) = "BIN B";
     979           0 :                 colHeadRange(3) = "BIN C";
     980           0 :                 colHeadRange(4) = "BIN D";
     981           0 :                 colHeadRange(5) = "BIN E";
     982           0 :                 colHeadRange(6) = "BIN F";
     983           0 :                 colHeadRange(7) = "BIN G";
     984           0 :                 colHeadRange(8) = "BIN H";
     985           0 :                 colHeadRange(9) = "BIN I";
     986           0 :                 colHeadRange(10) = "BIN J";
     987           0 :                 for (int iBin = 0; iBin != 10; iBin++) {
     988             :                     // colHeadRange( iBin + 1 ) = "BIN " + ( char )( iBin + 65 ); // not sure why this does not work
     989           0 :                     tableBodyRange(iBin + 1, 1) = OutputReportTabular::RealToStr(binBottom + float(iBin) * intervalSize, fldStIt->m_showDigits);
     990           0 :                     tableBodyRange(iBin + 1, 2) = OutputReportTabular::RealToStr(binBottom + float(iBin + 1) * intervalSize, fldStIt->m_showDigits);
     991             :                 }
     992           0 :                 if (produceTabular_para) {
     993           0 :                     OutputReportTabular::WriteSubtitle(state, "Bin Sizes for: " + fldStIt->m_colHead);
     994           0 :                     OutputReportTabular::WriteTable(
     995           0 :                         state, tableBodyRange, rowHeadRange, colHeadRange, colWidthRange, true); // transpose annual XML tables.
     996             :                 }
     997           0 :                 if (produceSQLite_para) {
     998           0 :                     if (state.dataSQLiteProcedures->sqlite) {
     999           0 :                         state.dataSQLiteProcedures->sqlite->createSQLiteTabularDataRecords(
    1000             :                             tableBodyRange, rowHeadRange, colHeadRange, m_name, "Entire Facility", "Bin Sizes");
    1001             :                     }
    1002             :                 }
    1003             :             }
    1004             :         }
    1005             :     }
    1006           0 : }
    1007             : 
    1008           0 : std::vector<std::string> AnnualTable::setupAggString()
    1009             : {
    1010           0 :     std::vector<std::string> retStringVec;
    1011           0 :     retStringVec.resize(20);
    1012           0 :     retStringVec[AnnualFieldSet::AggregationKind::sumOrAvg] = "";
    1013           0 :     retStringVec[AnnualFieldSet::AggregationKind::maximum] = " MAXIMUM ";
    1014           0 :     retStringVec[AnnualFieldSet::AggregationKind::minimum] = " MINIMUM ";
    1015           0 :     retStringVec[AnnualFieldSet::AggregationKind::valueWhenMaxMin] = " AT MAX/MIN ";
    1016           0 :     retStringVec[AnnualFieldSet::AggregationKind::hoursZero] = " HOURS ZERO ";
    1017           0 :     retStringVec[AnnualFieldSet::AggregationKind::hoursNonZero] = " HOURS NON-ZERO ";
    1018           0 :     retStringVec[AnnualFieldSet::AggregationKind::hoursPositive] = " HOURS POSITIVE ";
    1019           0 :     retStringVec[AnnualFieldSet::AggregationKind::hoursNonPositive] = " HOURS NON-POSITIVE ";
    1020           0 :     retStringVec[AnnualFieldSet::AggregationKind::hoursNegative] = " HOURS NEGATIVE ";
    1021           0 :     retStringVec[AnnualFieldSet::AggregationKind::hoursNonNegative] = " HOURS NON-NEGATIVE ";
    1022           0 :     retStringVec[AnnualFieldSet::AggregationKind::hoursInTenPercentBins] = " HOURS IN";            // " HOURS IN TEN PERCENT BINS ";
    1023           0 :     retStringVec[AnnualFieldSet::AggregationKind::hoursInTenBinsMinToMax] = " HOURS IN";           // " HOURS IN TEN BINS MIN TO MAX ";
    1024           0 :     retStringVec[AnnualFieldSet::AggregationKind::hoursInTenBinsZeroToMax] = " HOURS IN";          // " HOURS IN TEN BINS ZERO TO MAX ";
    1025           0 :     retStringVec[AnnualFieldSet::AggregationKind::hoursInTenBinsMinToZero] = " HOURS IN";          // " HOURS IN TEN BINS MIN TO ZERO ";
    1026           0 :     retStringVec[AnnualFieldSet::AggregationKind::hoursInTenBinsPlusMinusTwoStdDev] = " HOURS IN"; // " HOURS IN TEN BINS PLUS OR MINUS TWO STD DEV ";
    1027           0 :     retStringVec[AnnualFieldSet::AggregationKind::hoursInTenBinsPlusMinusThreeStdDev] =
    1028             :         " HOURS IN"; // " HOURS IN TEN BINS PLUS OR MINUS THREE STD DEV ";
    1029           0 :     retStringVec[AnnualFieldSet::AggregationKind::noAggregation] = " NO AGGREGATION ";
    1030           0 :     retStringVec[AnnualFieldSet::AggregationKind::sumOrAverageHoursShown] = " FOR HOURS SHOWN ";
    1031           0 :     retStringVec[AnnualFieldSet::AggregationKind::maximumDuringHoursShown] = " MAX FOR HOURS SHOWN ";
    1032           0 :     retStringVec[AnnualFieldSet::AggregationKind::minimumDuringHoursShown] = " MIN FOR HOURS SHOWN ";
    1033           0 :     return retStringVec;
    1034             : }
    1035             : 
    1036           0 : Real64 AnnualTable::setEnergyUnitStringAndFactor(OutputReportTabular::UnitsStyle const unitsStyle, std::string &unitString)
    1037             : {
    1038             :     Real64 convFactor;
    1039             :     // set the unit conversion
    1040           0 :     if (unitsStyle == OutputReportTabular::UnitsStyle::None) {
    1041           0 :         unitString = "J";
    1042           0 :         convFactor = 1.0;
    1043           0 :     } else if (unitsStyle == OutputReportTabular::UnitsStyle::JtoKWH) {
    1044           0 :         unitString = "kWh";
    1045           0 :         convFactor = 1.0 / 3600000.0;
    1046           0 :     } else if (unitsStyle == OutputReportTabular::UnitsStyle::JtoMJ) {
    1047           0 :         unitString = "MJ";
    1048           0 :         convFactor = 1.0 / 1000000.0;
    1049           0 :     } else if (unitsStyle == OutputReportTabular::UnitsStyle::JtoGJ) {
    1050           0 :         unitString = "GJ";
    1051           0 :         convFactor = 1.0 / 1000000000.0;
    1052             :     } else { // Should never happen but assures compilers of initialization
    1053           0 :         unitString = "J";
    1054           0 :         convFactor = 1.0;
    1055             :     }
    1056           0 :     return convFactor;
    1057             : }
    1058             : 
    1059           0 : void AnnualTable::fixUnitsPerSecond(std::string &unitString, Real64 &conversionFactor)
    1060             : {
    1061           0 :     if (unitString == "J/s") {
    1062           0 :         unitString = "W";
    1063           0 :     } else if (unitString == "kWh/s") {
    1064           0 :         unitString = "W";
    1065           0 :         conversionFactor *= 3600000.0;
    1066           0 :     } else if (unitString == "GJ/s") {
    1067           0 :         unitString = "kW";
    1068           0 :         conversionFactor *= 1000000.0;
    1069           0 :     } else if (unitString == "MJ/s") {
    1070           0 :         unitString = "kW";
    1071           0 :         conversionFactor *= 1000.0;
    1072           0 :     } else if (unitString == "therm/s") {
    1073           0 :         unitString = "kBtu/h";
    1074           0 :         conversionFactor *= 360000.0;
    1075           0 :     } else if (unitString == "kBtu/s") {
    1076           0 :         unitString = "kBtu/h";
    1077           0 :         conversionFactor *= 3600.0;
    1078           0 :     } else if (unitString == "ton-hrs/s") {
    1079           0 :         unitString = "ton";
    1080           0 :         conversionFactor *= 3600.0;
    1081             :     }
    1082           0 : }
    1083             : 
    1084           0 : AnnualFieldSet::AggregationKind stringToAggKind(EnergyPlusData &state, std::string inString)
    1085             : // Jason Glazer, August 2015
    1086             : // The function converts a string into an enumeration that describes the type of aggregation
    1087             : // used in REPORT:TABLE:ANNUAL.
    1088             : {
    1089             :     AnnualFieldSet::AggregationKind outAggType;
    1090             : 
    1091           0 :     if (UtilityRoutines::SameString(inString, "SumOrAverage")) {
    1092           0 :         outAggType = AnnualFieldSet::AggregationKind::sumOrAvg;
    1093           0 :     } else if (UtilityRoutines::SameString(inString, "Maximum")) {
    1094           0 :         outAggType = AnnualFieldSet::AggregationKind::maximum;
    1095           0 :     } else if (UtilityRoutines::SameString(inString, "Minimum")) {
    1096           0 :         outAggType = AnnualFieldSet::AggregationKind::minimum;
    1097           0 :     } else if (UtilityRoutines::SameString(inString, "ValueWhenMaximumOrMinimum")) {
    1098           0 :         outAggType = AnnualFieldSet::AggregationKind::valueWhenMaxMin;
    1099           0 :     } else if (UtilityRoutines::SameString(inString, "HoursZero")) {
    1100           0 :         outAggType = AnnualFieldSet::AggregationKind::hoursZero;
    1101           0 :     } else if (UtilityRoutines::SameString(inString, "HoursNonzero")) {
    1102           0 :         outAggType = AnnualFieldSet::AggregationKind::hoursNonZero;
    1103           0 :     } else if (UtilityRoutines::SameString(inString, "HoursPositive")) {
    1104           0 :         outAggType = AnnualFieldSet::AggregationKind::hoursPositive;
    1105           0 :     } else if (UtilityRoutines::SameString(inString, "HoursNonpositive")) {
    1106           0 :         outAggType = AnnualFieldSet::AggregationKind::hoursNonPositive;
    1107           0 :     } else if (UtilityRoutines::SameString(inString, "HoursNegative")) {
    1108           0 :         outAggType = AnnualFieldSet::AggregationKind::hoursNegative;
    1109           0 :     } else if (UtilityRoutines::SameString(inString, "HoursNonNegative")) {
    1110           0 :         outAggType = AnnualFieldSet::AggregationKind::hoursNonNegative;
    1111           0 :     } else if (UtilityRoutines::SameString(inString, "HoursInTenPercentBins")) {
    1112           0 :         outAggType = AnnualFieldSet::AggregationKind::hoursInTenPercentBins;
    1113           0 :     } else if (UtilityRoutines::SameString(inString, "HourInTenBinsMinToMax")) {
    1114           0 :         outAggType = AnnualFieldSet::AggregationKind::hoursInTenBinsMinToMax;
    1115           0 :     } else if (UtilityRoutines::SameString(inString, "HourInTenBinsZeroToMax")) {
    1116           0 :         outAggType = AnnualFieldSet::AggregationKind::hoursInTenBinsZeroToMax;
    1117           0 :     } else if (UtilityRoutines::SameString(inString, "HourInTenBinsMinToZero")) {
    1118           0 :         outAggType = AnnualFieldSet::AggregationKind::hoursInTenBinsMinToZero;
    1119           0 :     } else if (UtilityRoutines::SameString(inString, "HoursInTenBinsPlusMinusTwoStdDev")) {
    1120           0 :         outAggType = AnnualFieldSet::AggregationKind::hoursInTenBinsPlusMinusTwoStdDev;
    1121           0 :     } else if (UtilityRoutines::SameString(inString, "HoursInTenBinsPlusMinusThreeStdDev")) {
    1122           0 :         outAggType = AnnualFieldSet::AggregationKind::hoursInTenBinsPlusMinusThreeStdDev;
    1123           0 :     } else if (UtilityRoutines::SameString(inString, "NoAggregation")) {
    1124           0 :         outAggType = AnnualFieldSet::AggregationKind::noAggregation;
    1125           0 :     } else if (UtilityRoutines::SameString(inString, "SumOrAverageDuringHoursShown")) {
    1126           0 :         outAggType = AnnualFieldSet::AggregationKind::sumOrAverageHoursShown;
    1127           0 :     } else if (UtilityRoutines::SameString(inString, "MaximumDuringHoursShown")) {
    1128           0 :         outAggType = AnnualFieldSet::AggregationKind::maximumDuringHoursShown;
    1129           0 :     } else if (UtilityRoutines::SameString(inString, "MinimumDuringHoursShown")) {
    1130           0 :         outAggType = AnnualFieldSet::AggregationKind::minimumDuringHoursShown;
    1131             :     } else {
    1132           0 :         outAggType = AnnualFieldSet::AggregationKind::sumOrAvg;
    1133           0 :         ShowWarningError(state, "Invalid aggregation type=\"" + inString + "\"  Defaulting to SumOrAverage.");
    1134             :     }
    1135           0 :     return outAggType;
    1136             : }
    1137             : 
    1138           0 : int AnnualTable::columnCountForAggregation(AnnualFieldSet::AggregationKind curAgg)
    1139             : {
    1140           0 :     int returnCount = 0;
    1141           0 :     if (curAgg == AnnualFieldSet::AggregationKind::sumOrAvg || curAgg == AnnualFieldSet::AggregationKind::valueWhenMaxMin ||
    1142           0 :         curAgg == AnnualFieldSet::AggregationKind::hoursZero || curAgg == AnnualFieldSet::AggregationKind::hoursNonZero ||
    1143           0 :         curAgg == AnnualFieldSet::AggregationKind::hoursPositive || curAgg == AnnualFieldSet::AggregationKind::hoursNonPositive ||
    1144           0 :         curAgg == AnnualFieldSet::AggregationKind::hoursNegative || curAgg == AnnualFieldSet::AggregationKind::hoursNonNegative ||
    1145           0 :         curAgg == AnnualFieldSet::AggregationKind::sumOrAverageHoursShown || curAgg == AnnualFieldSet::AggregationKind::noAggregation) {
    1146           0 :         returnCount = 1;
    1147           0 :     } else if (curAgg == AnnualFieldSet::AggregationKind::maximum || curAgg == AnnualFieldSet::AggregationKind::minimum ||
    1148           0 :                curAgg == AnnualFieldSet::AggregationKind::maximumDuringHoursShown ||
    1149             :                curAgg == AnnualFieldSet::AggregationKind::minimumDuringHoursShown) {
    1150           0 :         returnCount = 2;
    1151           0 :     } else if (curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsMinToMax) {
    1152           0 :         returnCount = 10;
    1153           0 :     } else if (curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsZeroToMax ||
    1154             :                curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsMinToZero) {
    1155           0 :         returnCount = 11;
    1156           0 :     } else if (curAgg == AnnualFieldSet::AggregationKind::hoursInTenPercentBins ||
    1157           0 :                curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsPlusMinusTwoStdDev ||
    1158             :                curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsPlusMinusThreeStdDev) {
    1159           0 :         returnCount = 12;
    1160             :     }
    1161           0 :     return returnCount;
    1162             : }
    1163             : 
    1164           0 : std::string AnnualTable::trim(const std::string &str)
    1165             : {
    1166           0 :     std::string whitespace = " \t";
    1167           0 :     const auto strBegin = str.find_first_not_of(whitespace);
    1168           0 :     if (strBegin == std::string::npos) return ""; // no content
    1169             : 
    1170           0 :     const auto strEnd = str.find_last_not_of(whitespace);
    1171           0 :     const auto strRange = strEnd - strBegin + 1;
    1172             : 
    1173           0 :     return str.substr(strBegin, strRange);
    1174             : }
    1175             : 
    1176           2 : void AddAnnualTableOfContents(EnergyPlusData &state, std::ostream &nameOfStream)
    1177             : {
    1178             :     // Jason Glazer, August 2015
    1179             :     // This function is not part of the class but acts as an interface between procedural code and the class by
    1180             :     // invoking the writeTable member function for each of the AnnualTable objects
    1181           4 :     std::vector<AnnualTable>::iterator annualTableIt;
    1182           2 :     auto &annualTables(state.dataOutputReportTabularAnnual->annualTables);
    1183           2 :     for (annualTableIt = annualTables.begin(); annualTableIt != annualTables.end(); ++annualTableIt) {
    1184           0 :         annualTableIt->addTableOfContents(nameOfStream);
    1185             :     }
    1186           2 : }
    1187             : 
    1188           0 : void AnnualTable::addTableOfContents(std::ostream &nameOfStream)
    1189             : {
    1190           0 :     nameOfStream << "<p><b>" << m_name << "</b></p> |\n";
    1191           0 :     nameOfStream << "<a href=\"#" << OutputReportTabular::MakeAnchorName(m_name, "Entire Facility") << "\">"
    1192             :                  << "Entire Facility"
    1193           0 :                  << "</a>    |   \n";
    1194           0 : }
    1195             : 
    1196           0 : void AnnualTable::computeBinColumns(EnergyPlusData &state, OutputReportTabular::UnitsStyle const unitsStyle_para)
    1197             : {
    1198           0 :     std::vector<AnnualFieldSet>::iterator fldStIt;
    1199           0 :     Real64 constexpr veryLarge = 1.0E280;
    1200           0 :     Real64 constexpr verySmall = -1.0E280;
    1201           0 :     for (fldStIt = m_annualFields.begin(); fldStIt != m_annualFields.end(); ++fldStIt) {
    1202           0 :         int curAgg = fldStIt->m_aggregate;
    1203             :         // for columns with binning aggregation types compute the statistics
    1204           0 :         if (curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsMinToMax || curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsZeroToMax ||
    1205           0 :             curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsMinToZero || curAgg == AnnualFieldSet::AggregationKind::hoursInTenPercentBins ||
    1206           0 :             curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsPlusMinusTwoStdDev ||
    1207             :             curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsPlusMinusThreeStdDev) {
    1208             :             // the size the deferred vectors should be same for all rows
    1209           0 :             if (allRowsSameSizeDefferedVectors(fldStIt)) {
    1210           0 :                 convertUnitForDeferredResults(state, fldStIt, unitsStyle_para);
    1211           0 :                 std::vector<Real64> deferredTotalForColumn;
    1212           0 :                 Real64 minVal = veryLarge;
    1213           0 :                 Real64 maxVal = verySmall;
    1214           0 :                 Real64 sum = 0;
    1215           0 :                 Real64 curVal = 0.0;
    1216           0 :                 for (unsigned int jDefRes = 0; jDefRes != fldStIt->m_cell[0].deferredResults.size(); jDefRes++) {
    1217           0 :                     sum = 0;
    1218           0 :                     for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
    1219           0 :                         curVal = fldStIt->m_cell[row].deferredResults[jDefRes];
    1220           0 :                         sum += curVal;
    1221           0 :                         if (curVal > maxVal) {
    1222           0 :                             maxVal = curVal;
    1223             :                         }
    1224           0 :                         if (curVal < minVal) {
    1225           0 :                             minVal = curVal;
    1226             :                         }
    1227             :                     }
    1228           0 :                     deferredTotalForColumn.push_back(sum / float(m_objectNames.size())); // put average value into the total row
    1229             :                 }
    1230           0 :                 if (curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsMinToMax) {
    1231           0 :                     fldStIt->m_topBinValue = maxVal;
    1232           0 :                     fldStIt->m_bottomBinValue = minVal;
    1233           0 :                 } else if (curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsZeroToMax) {
    1234           0 :                     fldStIt->m_topBinValue = maxVal;
    1235           0 :                     fldStIt->m_bottomBinValue = 0.0;
    1236           0 :                 } else if (curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsMinToZero) {
    1237           0 :                     fldStIt->m_topBinValue = 0.0;
    1238           0 :                     fldStIt->m_bottomBinValue = minVal;
    1239           0 :                 } else if (curAgg == AnnualFieldSet::AggregationKind::hoursInTenPercentBins) {
    1240           0 :                     fldStIt->m_topBinValue = 1.0;
    1241           0 :                     fldStIt->m_bottomBinValue = 0.0;
    1242             :                 } else if (curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsPlusMinusTwoStdDev) {
    1243             :                 } else if (curAgg == AnnualFieldSet::AggregationKind::hoursInTenBinsPlusMinusThreeStdDev) {
    1244             :                 }
    1245             :                 // compute the actual amount of time spent in each bin and above and below
    1246           0 :                 for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
    1247           0 :                     fldStIt->m_cell[row].m_timeInBin = calculateBins(10,
    1248           0 :                                                                      fldStIt->m_cell[row].deferredResults,
    1249           0 :                                                                      fldStIt->m_cell[row].deferredElapsed,
    1250           0 :                                                                      fldStIt->m_topBinValue,
    1251           0 :                                                                      fldStIt->m_bottomBinValue,
    1252           0 :                                                                      fldStIt->m_cell[row].m_timeAboveTopBin,
    1253           0 :                                                                      fldStIt->m_cell[row].m_timeBelowBottomBin);
    1254             :                 }
    1255             :                 // do the total row binning
    1256           0 :                 fldStIt->m_timeInBinTotal = calculateBins(10,
    1257             :                                                           deferredTotalForColumn,
    1258           0 :                                                           fldStIt->m_cell[0].deferredElapsed,
    1259           0 :                                                           fldStIt->m_topBinValue,
    1260           0 :                                                           fldStIt->m_bottomBinValue,
    1261           0 :                                                           fldStIt->m_timeAboveTopBinTotal,
    1262           0 :                                                           fldStIt->m_timeBelowBottomBinTotal);
    1263             :             }
    1264             :         }
    1265             :     }
    1266           0 : }
    1267             : 
    1268           0 : bool AnnualTable::allRowsSameSizeDefferedVectors(std::vector<AnnualFieldSet>::iterator fldStIt)
    1269             : {
    1270           0 :     bool returnFlag = true;
    1271           0 :     unsigned int sizeOfDeferred = 0;
    1272           0 :     for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
    1273           0 :         if (sizeOfDeferred == 0) {
    1274           0 :             sizeOfDeferred = fldStIt->m_cell[row].deferredResults.size();
    1275             :         } else {
    1276           0 :             if (fldStIt->m_cell[row].deferredResults.size() != sizeOfDeferred) {
    1277           0 :                 returnFlag = false;
    1278           0 :                 return returnFlag;
    1279             :             }
    1280             :         }
    1281             :     }
    1282           0 :     return returnFlag;
    1283             : }
    1284             : 
    1285           0 : void AnnualTable::convertUnitForDeferredResults(EnergyPlusData &state,
    1286             :                                                 std::vector<AnnualFieldSet>::iterator fldStIt,
    1287             :                                                 OutputReportTabular::UnitsStyle const unitsStyle)
    1288             : {
    1289             :     Real64 curConversionFactor;
    1290             :     Real64 curConversionOffset;
    1291           0 :     std::string varNameWithUnits;
    1292             :     int indexUnitConv;
    1293           0 :     std::string curUnits;
    1294           0 :     std::string energyUnitsString;
    1295             :     Real64 curSI;
    1296             :     Real64 curIP;
    1297           0 :     Real64 energyUnitsConversionFactor = AnnualTable::setEnergyUnitStringAndFactor(unitsStyle, energyUnitsString);
    1298             :     // do the unit conversions
    1299           0 :     if (unitsStyle == OutputReportTabular::UnitsStyle::InchPound) {
    1300           0 :         varNameWithUnits = fldStIt->m_variMeter + " [" + unitEnumToString(fldStIt->m_varUnits) + ']';
    1301           0 :         OutputReportTabular::LookupSItoIP(state, varNameWithUnits, indexUnitConv, curUnits);
    1302           0 :         OutputReportTabular::GetUnitConversion(state, indexUnitConv, curConversionFactor, curConversionOffset, curUnits);
    1303             :     } else { // just do the Joule conversion
    1304             :         // if units is in Joules, convert if specified
    1305           0 :         if (fldStIt->m_varUnits == OutputProcessor::Unit::J) {
    1306           0 :             curUnits = energyUnitsString;
    1307           0 :             curConversionFactor = energyUnitsConversionFactor;
    1308           0 :             curConversionOffset = 0.0;
    1309             :         } else { // if not joules don't perform conversion
    1310           0 :             curUnits = unitEnumToString(fldStIt->m_varUnits);
    1311           0 :             curConversionFactor = 1.0;
    1312           0 :             curConversionOffset = 0.0;
    1313             :         }
    1314             :     }
    1315           0 :     if (fldStIt->m_varAvgSum == OutputProcessor::StoreType::Summed) {
    1316           0 :         curUnits += "/s";
    1317             :     }
    1318           0 :     fixUnitsPerSecond(curUnits, curConversionFactor);
    1319           0 :     if (curConversionFactor != 1.0 || curConversionOffset != 0.0) {
    1320           0 :         for (unsigned int row = 0; row != m_objectNames.size(); row++) { // loop through by row.
    1321           0 :             for (unsigned int jDefRes = 0; jDefRes != fldStIt->m_cell[0].deferredResults.size(); jDefRes++) {
    1322           0 :                 curSI = fldStIt->m_cell[row].deferredResults[jDefRes];
    1323           0 :                 curIP = curSI * curConversionFactor + curConversionOffset;
    1324           0 :                 fldStIt->m_cell[row].deferredResults[jDefRes] = curIP;
    1325             :             }
    1326             :         }
    1327             :     }
    1328           0 : }
    1329             : 
    1330           0 : std::vector<Real64> AnnualTable::calculateBins(int const numberOfBins,
    1331             :                                                std::vector<Real64> valuesToBin,
    1332             :                                                std::vector<Real64> corrElapsedTime,
    1333             :                                                Real64 const topOfBins,
    1334             :                                                Real64 const bottomOfBins,
    1335             :                                                Real64 &timeAboveTopBin,
    1336             :                                                Real64 &timeBelowBottomBin)
    1337             : {
    1338           0 :     std::vector<Real64> returnBins(0.0);
    1339           0 :     int binNum = 0;
    1340           0 :     returnBins.resize(numberOfBins);
    1341           0 :     Real64 intervalSize = (topOfBins - bottomOfBins) / float(numberOfBins);
    1342           0 :     timeAboveTopBin = 0.0;
    1343           0 :     timeBelowBottomBin = 0.0;
    1344           0 :     std::vector<Real64>::iterator elapsedTimeIt;
    1345           0 :     elapsedTimeIt = corrElapsedTime.begin();
    1346           0 :     std::vector<Real64>::iterator valueIt;
    1347           0 :     for (valueIt = valuesToBin.begin(); valueIt != valuesToBin.end(); ++valueIt) {
    1348           0 :         if (*valueIt < bottomOfBins) {
    1349           0 :             timeBelowBottomBin += *elapsedTimeIt;
    1350           0 :         } else if (*valueIt >= topOfBins) {
    1351           0 :             timeAboveTopBin += *elapsedTimeIt;
    1352             :         } else {
    1353             :             // determine which bin the results are in
    1354           0 :             binNum = int((*valueIt - bottomOfBins) / intervalSize);
    1355           0 :             returnBins[binNum] += *elapsedTimeIt;
    1356             :         }
    1357           0 :         ++elapsedTimeIt;
    1358             :     }
    1359           0 :     return returnBins;
    1360             : }
    1361             : 
    1362           0 : void AnnualTable::columnHeadersToTitleCase(EnergyPlusData &state)
    1363             : {
    1364           0 :     std::vector<AnnualFieldSet>::iterator fldStIt;
    1365           0 :     for (fldStIt = m_annualFields.begin(); fldStIt != m_annualFields.end(); ++fldStIt) {
    1366           0 :         if (fldStIt->m_variMeter == fldStIt->m_colHead) {
    1367           0 :             if (fldStIt->m_indexesForKeyVar.size() > 0) {
    1368           0 :                 int varNum = fldStIt->m_indexesForKeyVar[0];
    1369           0 :                 if (fldStIt->m_typeOfVar == OutputProcessor::VariableType::Real) {
    1370           0 :                     fldStIt->m_colHead = state.dataOutputProcessor->RVariableTypes(varNum).VarNameOnly;
    1371           0 :                 } else if (fldStIt->m_typeOfVar == OutputProcessor::VariableType::Meter) {
    1372           0 :                     fldStIt->m_colHead = state.dataOutputProcessor->EnergyMeters(varNum).Name;
    1373             :                 }
    1374             :             }
    1375             :         }
    1376             :     }
    1377           0 : }
    1378             : 
    1379           0 : void AnnualTable::clearTable()
    1380             : {
    1381           0 :     m_name = "";
    1382           0 :     m_filter = "";
    1383           0 :     m_scheduleName = "";
    1384           0 :     m_scheduleNum = 0;
    1385           0 :     m_objectNames.clear();
    1386           0 :     m_annualFields.clear();
    1387           0 : }
    1388             : 
    1389           0 : std::vector<std::string> AnnualTable::inspectTable()
    1390             : {
    1391             :     // added function just to inspect the main private AnnualTable members because no other
    1392             :     // interface to the AnnualTable class is output oriented except writeTable and that is very complex.
    1393           0 :     std::vector<std::string> ret;
    1394           0 :     ret.push_back(m_name);
    1395           0 :     ret.push_back(m_filter);
    1396           0 :     ret.push_back(m_scheduleName);
    1397           0 :     return ret;
    1398             : }
    1399             : 
    1400           0 : std::vector<std::string> AnnualTable::inspectTableFieldSets(int fldIndex)
    1401             : {
    1402             :     // added function just to inspect the private field set members of AnnualTable because no other
    1403             :     // interface to the AnnualTable class is output oriented except writeTable and that is very complex.
    1404           0 :     std::vector<std::string> ret;
    1405           0 :     AnnualFieldSet fldSt;
    1406           0 :     fldSt = m_annualFields[fldIndex];
    1407           0 :     ret.push_back(fldSt.m_colHead);
    1408           0 :     ret.push_back(fldSt.m_variMeter);
    1409           0 :     ret.push_back(unitEnumToString(fldSt.m_varUnits));
    1410           0 :     std::string outStr = std::to_string(fldSt.m_showDigits);
    1411             :     // ints
    1412           0 :     ret.push_back(outStr);
    1413           0 :     outStr = std::to_string(static_cast<int>(fldSt.m_typeOfVar));
    1414           0 :     ret.push_back(outStr);
    1415           0 :     outStr = std::to_string(fldSt.m_keyCount);
    1416           0 :     ret.push_back(outStr);
    1417           0 :     outStr = std::to_string(static_cast<int>(fldSt.m_varAvgSum));
    1418           0 :     ret.push_back(outStr);
    1419           0 :     outStr = std::to_string(static_cast<int>(fldSt.m_varStepType));
    1420           0 :     ret.push_back(outStr);
    1421           0 :     outStr = std::to_string(fldSt.m_aggregate);
    1422           0 :     ret.push_back(outStr);
    1423             :     // floats
    1424           0 :     outStr = std::to_string(fldSt.m_bottomBinValue);
    1425           0 :     ret.push_back(outStr);
    1426           0 :     outStr = std::to_string(fldSt.m_topBinValue);
    1427           0 :     ret.push_back(outStr);
    1428           0 :     outStr = std::to_string(fldSt.m_timeAboveTopBinTotal);
    1429           0 :     ret.push_back(outStr);
    1430           0 :     outStr = std::to_string(fldSt.m_timeBelowBottomBinTotal);
    1431           0 :     ret.push_back(outStr);
    1432             :     // cell value
    1433           0 :     if (fldSt.m_cell.size() > 0) {
    1434           0 :         outStr = std::to_string(fldSt.m_cell[0].result);
    1435           0 :         ret.push_back(outStr);
    1436             :     }
    1437           0 :     return ret;
    1438             : }
    1439             : 
    1440        2313 : } // namespace EnergyPlus::OutputReportTabularAnnual

Generated by: LCOV version 1.13