urbanopt-scenario 0.4.1 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/docs/package.json CHANGED
@@ -10,11 +10,11 @@
10
10
  },
11
11
  "author": "NREL",
12
12
  "dependencies": {
13
- "highlight.js": "^10.2.0",
13
+ "highlight.js": "^10.4.1",
14
14
  "json-schema-ref-parser": "^9.0.6",
15
15
  "json-schema-view-js": "git+https://git@github.com/bgschiller/json-schema-view-js.git",
16
- "vuepress": "^1.5.4",
17
- "webpack-dev-middleware": "^3.7.2"
16
+ "vuepress": "^1.6.0",
17
+ "webpack-dev-middleware": "^3.6.0"
18
18
  },
19
19
  "devDependencies": {
20
20
  "braces": "^3.0.2",
@@ -25,6 +25,7 @@
25
25
  "node-forge": ">=0.10.0",
26
26
  "serialize-javascript": "^5.0.1",
27
27
  "set-value": "^3.0.2",
28
- "yargs-parser": ">=18.1.1"
28
+ "yargs-parser": "^20.2.1",
29
+ "ini": "^2.0.0"
29
30
  }
30
31
  }
@@ -39,14 +39,15 @@ module URBANopt
39
39
  end
40
40
 
41
41
  ##
42
- # Returns the absolute path of the measures or nil if there is none, can be used when configuring OSWs.
42
+ # [return:] Absolute path of the measures or nil if there is none, can be used when configuring OSWs.
43
43
  def measures_dir
44
44
  return File.absolute_path(File.join(@root_dir, 'lib', 'measures'))
45
45
  end
46
46
 
47
47
  ##
48
48
  # Relevant files such as weather data, design days, etc.
49
- # Return the absolute path of the files or nil if there is none, used when configuring OSWs
49
+ ##
50
+ # [return:] Absolute path of the files or nil if there is none, used when configuring OSWs
50
51
  def files_dir
51
52
  return nil
52
53
  end
@@ -54,7 +55,8 @@ module URBANopt
54
55
  ##
55
56
  # Doc templates are common files like copyright files which are used to update measures and other code.
56
57
  # Doc templates will only be applied to measures in the current repository.
57
- # Return the absolute path of the doc templates dir or nil if there is none.
58
+ ##
59
+ # [return:] Absolute path of the doc templates dir or nil if there is none.
58
60
  def doc_templates_dir
59
61
  return File.absolute_path(File.join(@root_dir, 'doc_templates'))
60
62
  end
@@ -36,10 +36,10 @@ module URBANopt
36
36
  # Initialize ScenarioBase attributes: +name+ , +root directory+ , +run directory+ and +feature_file+
37
37
  ##
38
38
  # [parameters:]
39
- # +name+ - _String_ - Human readable scenario name.
40
- # +root_dir+ - _String_ - Root directory for the scenario, contains Gemfile describing dependencies.
41
- # +run_dir+ - _String_ - Directory for simulation of this scenario, deleting run directory clears the scenario.
42
- # +feature_file+ - _FeatureFile_ - An instance of +URBANopt::Core::FeatureFile+ containing features for simulation.
39
+ # * +name+ - _String_ - Human readable scenario name.
40
+ # * +root_dir+ - _String_ - Root directory for the scenario, contains Gemfile describing dependencies.
41
+ # * +run_dir+ - _String_ - Directory for simulation of this scenario, deleting run directory clears the scenario.
42
+ # * +feature_file+ - _FeatureFile_ - An instance of +URBANopt::Core::FeatureFile+ containing features for simulation.
43
43
  def initialize(name, root_dir, run_dir, feature_file)
44
44
  @name = name
45
45
  @root_dir = root_dir
@@ -42,14 +42,13 @@ module URBANopt
42
42
  # The CSV file has three columns 1) feature_id, 2) feature_name, and 3) mapper_class_name. There is one row for each Feature.
43
43
  ##
44
44
  # [parameters:]
45
- # +name+ - _String_ - Human readable scenario name.
46
- # +root_dir+ - _String_ - Root directory for the scenario, contains Gemfile describing dependencies.
47
- # +run_dir+ - _String_ - Directory for simulation of this scenario, deleting run directory clears the scenario.
48
- # +feature_file+ - _URBANopt::Core::FeatureFile_ - FeatureFile containing features to simulate.
49
- # +mapper_files_dir+ - _String_ - Directory containing all mapper class files containing MapperBase definitions.
50
- # +csv_file+ - _String_ - Path to CSV file assigning a MapperBase class to each feature in feature_file.
51
- # +num_header_rows+ - _Strng_ - Number of header rows to skip in CSV file.
52
-
45
+ # * +name+ - _String_ - Human readable scenario name.
46
+ # * +root_dir+ - _String_ - Root directory for the scenario, contains Gemfile describing dependencies.
47
+ # * +run_dir+ - _String_ - Directory for simulation of this scenario, deleting run directory clears the scenario.
48
+ # * +feature_file+ - _URBANopt::Core::FeatureFile_ - FeatureFile containing features to simulate.
49
+ # * +mapper_files_dir+ - _String_ - Directory containing all mapper class files containing MapperBase definitions.
50
+ # * +csv_file+ - _String_ - Path to CSV file assigning a MapperBase class to each feature in feature_file.
51
+ # * +num_header_rows+ - _String_ - Number of header rows to skip in CSV file.
53
52
  def initialize(name, root_dir, run_dir, feature_file, mapper_files_dir, csv_file, num_header_rows)
54
53
  super(name, root_dir, run_dir, feature_file)
55
54
  @mapper_files_dir = mapper_files_dir
@@ -38,10 +38,10 @@ module URBANopt
38
38
  # A Simulation Mapper will map the
39
39
  ##
40
40
  # [parameters:]
41
- # +scenario+ - _ScenarioBase_ - Scenario containing this ScenarioDatapoint.
42
- # +feature_id+ - _String_ - Unique id of the feature for this ScenarioDatapoint.
43
- # +feature_name+ - _String_ - Human readable name of the feature for this ScenarioDatapoint.
44
- # +mapper_class+ - _String_ - Name of Ruby class used to translate feature to simulation OSW.
41
+ # * +scenario+ - _ScenarioBase_ - Scenario containing this ScenarioDatapoint.
42
+ # * +feature_id+ - _String_ - Unique id of the feature for this ScenarioDatapoint.
43
+ # * +feature_name+ - _String_ - Human readable name of the feature for this ScenarioDatapoint.
44
+ # * +mapper_class+ - _String_ - Name of Ruby class used to translate feature to simulation OSW.
45
45
  def initialize(scenario, feature_id, feature_name, mapper_class)
46
46
  @scenario = scenario
47
47
  @feature_id = feature_id
@@ -35,7 +35,7 @@ module URBANopt
35
35
  # ScenarioPostProcessorBase post-processes a Scenario to create scenario level results.
36
36
  ##
37
37
  # [parameters:]
38
- # +scenario_base+ - _ScenarioBase_ - An object of ScenarioBase class.
38
+ # * +scenario_base+ - _ScenarioBase_ - An object of ScenarioBase class.
39
39
  def initialize(scenario_base)
40
40
  @scenario_base = scenario_base
41
41
  end
@@ -53,7 +53,7 @@ module URBANopt
53
53
  # Add results from a simulation_dir to this result.
54
54
  ##
55
55
  # [parameters:]
56
- # +simulation_dir+ - _SimulationDirOSW_ - An object on SimulationDirOSW class.
56
+ # * +simulation_dir+ - _SimulationDirOSW_ - An object on SimulationDirOSW class.
57
57
  def add_simulation_dir(simulation_dir)
58
58
  raise 'add_simulation_dir not implemented for ScenarioPostProcessorBase, override in your class'
59
59
  end
@@ -32,8 +32,6 @@ require 'urbanopt/scenario/scenario_post_processor_base'
32
32
  require 'urbanopt/reporting/default_reports'
33
33
 
34
34
  require 'csv'
35
- require 'json'
36
- require 'fileutils'
37
35
  require 'sqlite3'
38
36
 
39
37
  module URBANopt
@@ -43,7 +41,7 @@ module URBANopt
43
41
  # ScenarioPostProcessorBase post-processes a scenario to create scenario level results
44
42
  ##
45
43
  # [parameters:]
46
- # +scenario_base+ - _ScenarioBase_ - An object of ScenarioBase class.
44
+ # * +scenario_base+ - _ScenarioBase_ - An object of ScenarioBase class.
47
45
  def initialize(scenario_base)
48
46
  super(scenario_base)
49
47
 
@@ -69,7 +67,7 @@ module URBANopt
69
67
  # Add results from a simulation_dir to this result.
70
68
  ##
71
69
  # [parameters:]
72
- # +simulation_dir+ - _SimulationDirOSW_ - An object on SimulationDirOSW class.
70
+ # * +simulation_dir+ - _SimulationDirOSW_ - An object on SimulationDirOSW class.
73
71
  def add_simulation_dir(simulation_dir)
74
72
  feature_reports = URBANopt::Reporting::DefaultReports::FeatureReport.from_simulation_dir(simulation_dir)
75
73
 
@@ -86,26 +84,36 @@ module URBANopt
86
84
 
87
85
  # Create database file with scenario-level results
88
86
  # Sum values for each timestep across all features. Save to new table in a new database
87
+ ##
88
+ # [parameters:]
89
+ # * +file_name+ - _String_ - Assign a name to the saved scenario results file
89
90
  def create_scenario_db_file(file_name = @default_save_name)
90
91
  new_db_file = File.join(@initialization_hash[:directory_name], "#{file_name}.db")
91
92
  scenario_db = SQLite3::Database.open new_db_file
92
93
  scenario_db.execute "CREATE TABLE IF NOT EXISTS ReportData(
93
94
  TimeIndex INTEGER,
94
- ReportDataDictionaryIndex INTEGER,
95
- Value INTEGER
95
+ Year VARCHAR(255),
96
+ Month VARCHAR(255),
97
+ Day VARCHAR(255),
98
+ Hour VARCHAR(255),
99
+ Minute VARCHAR(255),
100
+ Dst INTEGER,
101
+ FuelType VARCHAR(255),
102
+ Value INTEGER,
103
+ FuelUnits VARCHAR(255)
96
104
  )"
97
105
 
98
106
  values_arr = []
99
107
  feature_list = Pathname.new(@initialization_hash[:directory_name]).children.select(&:directory?) # Folders in the run/scenario directory
100
-
108
+
101
109
  # get scenario CSV
102
110
  scenario_csv = File.join(@initialization_hash[:root_dir], @initialization_hash[:name] + '.csv')
103
111
  if File.exist?(scenario_csv)
104
112
  # csv found
105
- feature_ids = CSV.read(scenario_csv, :headers => true)
113
+ feature_ids = CSV.read(scenario_csv, headers: true)
106
114
  feature_list = []
107
115
  # loop through building feature ids from scenario csv
108
- feature_ids["Feature Id"].each do |feature|
116
+ feature_ids['Feature Id'].each do |feature|
109
117
  if Dir.exist?(File.join(@initialization_hash[:directory_name], feature))
110
118
  feature_list << File.join(@initialization_hash[:directory_name], feature)
111
119
  else
@@ -115,46 +123,54 @@ module URBANopt
115
123
  else
116
124
  raise "Couldn't find scenario CSV: #{scenario_csv}"
117
125
  end
118
- feature_1_name = File.basename(feature_list[0]) # Get name of first feature, so we can read eplusout.sql from there
119
- uo_output_sql_file = File.join(@initialization_hash[:directory_name], feature_1_name, 'eplusout.sql')
120
126
  feature_list.each do |feature| # Loop through each feature in the scenario
127
+ uo_output_sql_file = File.join(@initialization_hash[:directory_name], File.basename(feature), 'eplusout.sql')
121
128
  feature_db = SQLite3::Database.open uo_output_sql_file
122
129
  # Doing "db.results_as_hash = true" is prettier, but in this case significantly slower.
123
130
 
124
- # RDDI == 10 is the timestep value for facility electricity
125
- elec_query = feature_db.query "SELECT TimeIndex, Value
126
- FROM ReportData
127
- WHERE (TimeIndex % 2) != 0
128
- AND ReportDataDictionaryIndex=10 order by TimeIndex"
131
+ elec_query = feature_db.query "SELECT ReportData.TimeIndex, Time.Year, Time.Month, Time.Day, Time.Hour,
132
+ Time.Minute, Time.Dst, ReportData.Value
133
+ FROM ReportData
134
+ INNER JOIN Time ON Time.TimeIndex=ReportData.TimeIndex
135
+ INNER JOIN ReportDataDictionary AS rddi ON rddi.ReportDataDictionaryIndex=ReportData.ReportDataDictionaryIndex
136
+ WHERE rddi.IndexGroup == 'Facility:Electricity'
137
+ AND rddi.ReportingFrequency == 'Zone Timestep'
138
+ AND Time.Year > 1900
139
+ ORDER BY ReportData.TimeIndex"
129
140
 
130
141
  elec_query.each do |row| # Add up all the values for electricity usage across all Features at this timestep
131
142
  # row[0] == TimeIndex, row[1] == Value
143
+
132
144
  arr_match = values_arr.find { |v| v[:time_index] == row[0] }
133
145
  if arr_match.nil?
134
146
  # add new row to value_arr
135
- values_arr << { time_index: row[0], elec_val: Float(row[1]), gas_val: 0 }
147
+ values_arr << { time_index: row[0], year: row[1], month: row[2], day: row[3], hour: row[4], minute: row[5], dst: row[6], elec_val: Float(row[7]), gas_val: 0 }
136
148
  else
137
149
  # running sum
138
- arr_match[:elec_val] += Float(row[1])
150
+ arr_match[:elec_val] += Float(row[7])
139
151
  end
140
152
  end # End elec_query
141
153
  elec_query.close
142
154
 
143
- # RDDI == 255 is the timestep value for facility gas
144
- gas_query = feature_db.query "SELECT TimeIndex, Value
145
- FROM ReportData
146
- WHERE (TimeIndex % 2) != 0
147
- AND ReportDataDictionaryIndex=255 order by TimeIndex"
155
+ gas_query = feature_db.query "SELECT ReportData.TimeIndex, Time.Year, Time.Month, Time.Day, Time.Hour,
156
+ Time.Minute, Time.Dst, ReportData.Value
157
+ FROM ReportData
158
+ INNER JOIN Time ON Time.TimeIndex=ReportData.TimeIndex
159
+ INNER JOIN ReportDataDictionary AS rddi ON rddi.ReportDataDictionaryIndex=ReportData.ReportDataDictionaryIndex
160
+ WHERE rddi.IndexGroup == 'Facility:Gas'
161
+ AND rddi.ReportingFrequency == 'Zone Timestep'
162
+ AND Time.Year > 1900
163
+ ORDER BY ReportData.TimeIndex"
148
164
 
149
165
  gas_query.each do |row|
150
166
  # row[0] == TimeIndex, row[1] == Value
151
167
  arr_match = values_arr.find { |v| v[:time_index] == row[0] }
152
168
  if arr_match.nil?
153
169
  # add new row to value_arr
154
- values_arr << { time_index: row[0], gas_val: Float(row[1]), elec_val: 0 }
170
+ values_arr << { time_index: row[0], year: row[1], month: row[2], day: row[3], hour: row[4], minute: row[5], dst: row[6], gas_val: Float(row[7]), elec_val: 0 }
155
171
  else
156
172
  # running sum
157
- arr_match[:gas_val] += Float(row[1])
173
+ arr_match[:gas_val] += Float(row[7])
158
174
  end
159
175
  end # End gas_query
160
176
  gas_query.close
@@ -164,13 +180,13 @@ module URBANopt
164
180
  elec_sql = []
165
181
  gas_sql = []
166
182
  values_arr.each do |i|
167
- elec_sql << "(#{i[:time_index]}, 10, #{i[:elec_val]})"
168
- gas_sql << "(#{i[:time_index]}, 255, #{i[:gas_val]})"
183
+ elec_sql << "(#{i[:time_index]}, #{i[:year]}, #{i[:month]}, #{i[:day]}, #{i[:hour]}, #{i[:minute]}, #{i[:dst]}, 'Electricity', #{i[:elec_val]}, 'J')"
184
+ gas_sql << "(#{i[:time_index]}, #{i[:year]}, #{i[:month]}, #{i[:day]}, #{i[:hour]}, #{i[:minute]}, #{i[:dst]}, 'Gas', #{i[:gas_val]}, 'J')"
169
185
  end
170
186
 
171
187
  # Put summed Values into the database
172
- scenario_db.execute("INSERT INTO ReportData (TimeIndex, ReportDataDictionaryIndex, Value) VALUES #{elec_sql.join(', ')}")
173
- scenario_db.execute("INSERT INTO ReportData (TimeIndex, ReportDataDictionaryIndex, Value) VALUES #{gas_sql.join(', ')}")
188
+ scenario_db.execute("INSERT INTO ReportData VALUES #{elec_sql.join(', ')}")
189
+ scenario_db.execute("INSERT INTO ReportData VALUES #{gas_sql.join(', ')}")
174
190
  scenario_db.close
175
191
  end
176
192
 
@@ -178,7 +194,7 @@ module URBANopt
178
194
  # Save scenario result
179
195
  ##
180
196
  # [parameters:]
181
- # +file_name+ - _String_ - Assign a name to the saved scenario results file
197
+ # * +file_name+ - _String_ - Assign a name to the saved scenario results file
182
198
  def save(file_name = @default_save_name)
183
199
  @scenario_result.save
184
200
 
@@ -34,7 +34,6 @@ require 'urbanopt/reporting/default_reports'
34
34
  require 'csv'
35
35
  require 'json'
36
36
  require 'fileutils'
37
- require 'pathname'
38
37
 
39
38
  module URBANopt
40
39
  module Scenario
@@ -43,8 +42,8 @@ module URBANopt
43
42
  # OpenDSSPostProcessor post-processes OpenDSS results to selected OpenDSS results and integrate them in scenario and feature reports.
44
43
  ##
45
44
  # [parameters:]
46
- # +scenario_report+ - _ScenarioBase_ - An object of Scenario_report class.
47
- # +opendss_results_dir_name+ - _directory name of opendss results
45
+ # * +scenario_report+ - _ScenarioBase_ - An object of Scenario_report class.
46
+ # * +opendss_results_dir_name+ - _directory name of opendss results
48
47
  def initialize(scenario_report, opendss_results_dir_name = 'opendss')
49
48
  if !scenario_report.nil?
50
49
  @scenario_report = scenario_report
@@ -202,9 +201,9 @@ module URBANopt
202
201
  # Save csv report method
203
202
  ##
204
203
  # [parameters:]
205
- # +feature_report+ - _feature report object_ - An onject of the feature report
206
- # +updated_feature_report_csv+ - _CSV_ - An updated feature report csv
207
- # +file_name+ - _String_ - Assigned name to save the file with no extension
204
+ # * +feature_report+ - _feature report object_ - An onject of the feature report
205
+ # * +updated_feature_report_csv+ - _CSV_ - An updated feature report csv
206
+ # * +file_name+ - _String_ - Assigned name to save the file with no extension
208
207
  def save_csv(feature_report, updated_feature_report_csv, file_name = 'default_feature_report')
209
208
  File.write(File.join(feature_report.directory_name, 'feature_reports', "#{file_name}.csv"), updated_feature_report_csv)
210
209
  end
@@ -213,7 +212,7 @@ module URBANopt
213
212
  # create opendss json report results
214
213
  ##
215
214
  # [parameters:]
216
- # +feature_report+ - _feature report object_ - An onject of the feature report
215
+ # * +feature_report+ - _feature report object_ - An onject of the feature report
217
216
  def add_summary_results(feature_report)
218
217
  under_voltage_hrs = 0
219
218
  over_voltage_hrs = 0
@@ -258,7 +257,7 @@ module URBANopt
258
257
  updated_feature_csv = merge_data(@feature_reports_data[id], @opendss_data[id])
259
258
 
260
259
  # save fetaure reports
261
- feature_report.save_feature_report('default_feature_report_opendss')
260
+ feature_report.save_json_report('default_feature_report_opendss')
262
261
 
263
262
  # resave updated csv report
264
263
  save_csv(feature_report, updated_feature_csv, 'default_feature_report_opendss')
@@ -268,7 +267,8 @@ module URBANopt
268
267
  save_transformers_reports
269
268
 
270
269
  # save the updated scenario reports
271
- @scenario_report.save(file_name = 'scenario_report_opendss')
270
+ # set save_feature_reports to false since only the scenario reports should be saved now
271
+ @scenario_report.save(file_name = 'scenario_report_opendss', save_feature_reports = false)
272
272
  end
273
273
  end
274
274
  end
@@ -40,8 +40,9 @@ module URBANopt
40
40
  # Create all SimulationDirs for Scenario.
41
41
  ##
42
42
  # [parameters:]
43
- # +scenario+ - _ScenarioBase_ - Scenario to create simulation input files for scenario.
44
- # +force_clear+ - _Bool_ - Clear Scenario before creating simulation input files
43
+ # * +scenario+ - _ScenarioBase_ - Scenario to create simulation input files for scenario.
44
+ # * +force_clear+ - _Bool_ - Clear Scenario before creating simulation input files
45
+ ##
45
46
  # [return:] _Array_ Returns an array of all SimulationDirs, even those created previously, for Scenario.
46
47
  def create_simulation_files(scenario, force_clear = false)
47
48
  raise 'create_input_files is not implemented for ScenarioRunnerBase, override in your class'
@@ -51,9 +52,9 @@ module URBANopt
51
52
  # Create and run all SimulationFiles for Scenario.
52
53
  ##
53
54
  # [parameters:]
54
- # +scenario+ - _ScenarioBase_ - Scenario to create and run simulation input files for.
55
- # +force_clear+ - _Bool_ - Clear Scenario before creating Simulation input files.
56
- #
55
+ # * +scenario+ - _ScenarioBase_ - Scenario to create and run simulation input files for.
56
+ # * +force_clear+ - _Bool_ - Clear Scenario before creating Simulation input files.
57
+ ##
57
58
  # [return:] _Array_ Returns an array of all SimulationDirs, even those created previously, for Scenario.
58
59
  def run(scenario, force_clear = false, options = {})
59
60
  raise 'run is not implemented for ScenarioRunnerBase, override in your class'
@@ -46,8 +46,9 @@ module URBANopt
46
46
  # Create all OSWs for Scenario.
47
47
  ##
48
48
  # [parameters:]
49
- # +scenario+ - _ScenarioBase_ - Scenario to create simulation input files for.
50
- # +force_clear+ - _Bool_ - Clear Scenario before creating simulation input files.
49
+ # * +scenario+ - _ScenarioBase_ - Scenario to create simulation input files for.
50
+ # * +force_clear+ - _Bool_ - Clear Scenario before creating simulation input files.
51
+ ##
51
52
  # [return:] _Array_ Returns array of all SimulationDirs, even those created previously, for Scenario.
52
53
  def create_simulation_files(scenario, force_clear = false)
53
54
  if force_clear
@@ -79,8 +80,9 @@ module URBANopt
79
80
  # - Run osw file groups in order and store simulation failure in a array.
80
81
  ##
81
82
  # [parameters:]
82
- # +scenario+ - _ScenarioBase_ - Scenario to create and run SimulationFiles for.
83
- # +force_clear+ - _Bool_ - Clear Scenario before creating SimulationFiles.
83
+ # * +scenario+ - _ScenarioBase_ - Scenario to create and run SimulationFiles for.
84
+ # * +force_clear+ - _Bool_ - Clear Scenario before creating SimulationFiles.
85
+ ##
84
86
  # [return:] _Array_ Returns array of all SimulationFiles, even those created previously, for Scenario.
85
87
  def run(scenario, force_clear = false, options = {})
86
88
  # instantiate openstudio runner - use the defaults for now. If need to change then create
@@ -31,21 +31,22 @@
31
31
  require 'csv'
32
32
  require 'date'
33
33
  require 'json'
34
- require 'fileutils'
35
34
 
36
35
  module URBANopt
37
36
  module Scenario
38
37
  class ResultVisualization
39
- def self.create_visualization(run_dir, feature = true)
38
+ def self.create_visualization(run_dir, feature = true, feature_names = false)
40
39
  @all_results = []
40
+
41
41
  run_dir.each do |folder|
42
- name = folder.split('/')[-1]
43
-
44
42
  # create visualization for scenarios
45
43
  if feature == false
44
+ name = folder.split('/')[-1]
46
45
  csv_dir = File.join(folder, 'default_scenario_report.csv')
47
46
  # create visualization for features
48
47
  elsif feature == true
48
+ index = run_dir.index(folder)
49
+ name = folder.split('/')[-1] + '-' + feature_names[index]
49
50
  csv_dir = File.join(folder, 'feature_reports/default_feature_report.csv')
50
51
  end
51
52
 
@@ -181,14 +182,13 @@ module URBANopt
181
182
  monthly_sum_dec += v.to_f
182
183
  i += 1
183
184
  end
184
- # sum up all values for annual aggregate
185
- if k <= size
186
- annual_sum += v.to_f
187
- k += 1
188
- end
185
+
189
186
  end
190
187
  end
191
188
 
189
+ # sum up monthly values for annual aggregate
190
+ annual_sum = monthly_sum_jan + monthly_sum_feb + monthly_sum_mar + monthly_sum_apr + monthly_sum_may + monthly_sum_jun + monthly_sum_jul + monthly_sum_aug + monthly_sum_sep + monthly_sum_oct + monthly_sum_nov + monthly_sum_dec
191
+
192
192
  # store headers as key and monthly sums as values for each header
193
193
  monthly_totals[headers_unitless[j]] = [monthly_sum_jan, monthly_sum_feb, monthly_sum_mar, monthly_sum_apr, monthly_sum_may, monthly_sum_jun, monthly_sum_jul, monthly_sum_aug, monthly_sum_sep, monthly_sum_oct, monthly_sum_nov, monthly_sum_dec]
194
194
 
@@ -35,9 +35,9 @@ module URBANopt
35
35
  # SimulationDirBase is the agnostic representation of a directory of simulation input files.
36
36
  ##
37
37
  # [parameters:]
38
- # +scenario+ - _ScenarioBase_ - Scenario containing this SimulationDirBase.
39
- # +features+ - _Array_ - Array of Features that this SimulationDirBase represents.
40
- # +feature_names+ - _Array_ - Array of scenario specific names for these Features.
38
+ # * +scenario+ - _ScenarioBase_ - Scenario containing this SimulationDirBase.
39
+ # * +features+ - _Array_ - Array of Features that this SimulationDirBase represents.
40
+ # * +feature_names+ - _Array_ - Array of scenario specific names for these Features.
41
41
  def initialize(scenario, features, feature_names)
42
42
  @scenario = scenario
43
43
  @features = features