urbanopt-scenario 0.7.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/nightly_build.yml +40 -0
  3. data/CHANGELOG.md +31 -1
  4. data/Gemfile +2 -2
  5. data/LICENSE.md +1 -3
  6. data/README.md +5 -3
  7. data/doc_templates/LICENSE.md +37 -0
  8. data/doc_templates/README.md.erb +42 -0
  9. data/doc_templates/copyright_erb.txt +41 -0
  10. data/doc_templates/copyright_js.txt +4 -0
  11. data/doc_templates/copyright_ruby.txt +39 -0
  12. data/docs/package-lock.json +4712 -3863
  13. data/docs/package.json +1 -1
  14. data/lib/urbanopt/scenario/default_reports.rb +1 -1
  15. data/lib/urbanopt/scenario/extension.rb +1 -1
  16. data/lib/urbanopt/scenario/logger.rb +1 -1
  17. data/lib/urbanopt/scenario/scenario_base.rb +1 -1
  18. data/lib/urbanopt/scenario/scenario_csv.rb +1 -1
  19. data/lib/urbanopt/scenario/scenario_datapoint_base.rb +1 -1
  20. data/lib/urbanopt/scenario/scenario_post_processor_base.rb +1 -1
  21. data/lib/urbanopt/scenario/scenario_post_processor_default.rb +1 -1
  22. data/lib/urbanopt/scenario/scenario_post_processor_disco.rb +159 -0
  23. data/lib/urbanopt/scenario/scenario_post_processor_opendss.rb +159 -4
  24. data/lib/urbanopt/scenario/scenario_runner_base.rb +1 -1
  25. data/lib/urbanopt/scenario/scenario_runner_osw.rb +1 -1
  26. data/lib/urbanopt/scenario/scenario_visualization.rb +24 -7
  27. data/lib/urbanopt/scenario/simulation_dir_base.rb +1 -1
  28. data/lib/urbanopt/scenario/simulation_dir_osw.rb +1 -4
  29. data/lib/urbanopt/scenario/simulation_mapper_base.rb +1 -1
  30. data/lib/urbanopt/scenario/version.rb +2 -2
  31. data/lib/urbanopt/scenario.rb +2 -1
  32. data/lib/urbanopt-scenario.rb +1 -1
  33. data/urbanopt-scenario-gem.gemspec +4 -11
  34. metadata +41 -6
data/docs/package.json CHANGED
@@ -23,7 +23,7 @@
23
23
  "is-svg": ">=4.3.1",
24
24
  "js-yaml": "^3.14.0",
25
25
  "minimist": ">=1.2.3",
26
- "node-forge": ">=0.10.0",
26
+ "node-forge": ">=1.3.0",
27
27
  "postcss": "^8.2.15",
28
28
  "serialize-javascript": "^5.0.1",
29
29
  "set-value": "^4.0.1",
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -0,0 +1,159 @@
1
+ # *********************************************************************************
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
+ # contributors. All rights reserved.
4
+
5
+ # Redistribution and use in source and binary forms, with or without modification,
6
+ # are permitted provided that the following conditions are met:
7
+
8
+ # Redistributions of source code must retain the above copyright notice, this list
9
+ # of conditions and the following disclaimer.
10
+
11
+ # Redistributions in binary form must reproduce the above copyright notice, this
12
+ # list of conditions and the following disclaimer in the documentation and/or other
13
+ # materials provided with the distribution.
14
+
15
+ # Neither the name of the copyright holder nor the names of its contributors may be
16
+ # used to endorse or promote products derived from this software without specific
17
+ # prior written permission.
18
+
19
+ # Redistribution of this software, without modification, must refer to the software
20
+ # by the same designation. Redistribution of a modified version of this software
21
+ # (i) may not refer to the modified version by the same designation, or by any
22
+ # confusingly similar designation, and (ii) must refer to the underlying software
23
+ # originally provided by Alliance as “URBANopt”. Except to comply with the foregoing,
24
+ # the term “URBANopt”, or any confusingly similar designation may not be used to
25
+ # refer to any modified version of this software or any modified version of the
26
+ # underlying software originally provided by Alliance without the prior written
27
+ # consent of Alliance.
28
+
29
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
30
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32
+ # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33
+ # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
36
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
37
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
38
+ # OF THE POSSIBILITY OF SUCH DAMAGE.
39
+ # *********************************************************************************
40
+
41
+ require 'urbanopt/reporting/default_reports'
42
+
43
+ require 'csv'
44
+ require 'json'
45
+ require 'fileutils'
46
+
47
+ module URBANopt
48
+ module Scenario
49
+ class DISCOPostProcessor
50
+ ##
51
+ # DISCOPostProcessor post-processes DISCO results to selected DISCO results and
52
+ # integrate them in scenario and feature reports.
53
+ ##
54
+ # [parameters:]
55
+ # * +scenaro_report+ - _ScenarioBase_ - An object of Scenario_report class.
56
+ # * +disco_results_dir_name+ - _directory name of disco results
57
+ def initialize(scenario_report, disco_results_dir_name = 'disco')
58
+ if !scenario_report.nil?
59
+ @scenario_report = scenario_report
60
+ @disco_results_dir = File.join(@scenario_report.directory_name, disco_results_dir_name)
61
+ else
62
+ raise 'scenario_report is not valid'
63
+ end
64
+
65
+ # initialize disco data
66
+ @disco_data = {}
67
+
68
+ # initialize disco json results
69
+ @disco_json_results = {}
70
+
71
+ # initialize logger
72
+ @@logger ||= URBANopt::Reporting::DefaultReports.logger
73
+ end
74
+
75
+ # load disco data (if exists)
76
+ def load_disco_data
77
+
78
+ # load disco upgrade summary
79
+ disco_json_filename = File.join(@disco_results_dir, 'upgrade_summary.json')
80
+ if File.exist?(disco_json_filename)
81
+ @disco_json_results = JSON.parse(File.read(disco_json_filename))
82
+ end
83
+
84
+ end
85
+
86
+ # load disco data
87
+ def load_data
88
+ # load selected disco data
89
+ load_disco_data
90
+ end
91
+
92
+
93
+ ##
94
+ # save disco scenario fields
95
+ ##
96
+ def save_disco_scenario
97
+ @scenario_report.scenario_power_distribution_cost = URBANopt::Reporting::DefaultReports::ScenarioPowerDistributionCost.new
98
+
99
+ # RESULTS
100
+
101
+ res = []
102
+ # read result from JSON report
103
+ res = @disco_json_results['results']
104
+ @scenario_report.scenario_power_distribution_cost.results = res
105
+
106
+
107
+
108
+ # OUTPUTS
109
+
110
+ out = {}
111
+ # read result from JSON report
112
+ out[:log_file] = @disco_json_results['outputs']['log_file']
113
+ out[:jobs] = []
114
+ @disco_json_results['outputs']['jobs'].each do |job|
115
+ out[:jobs] << job
116
+ end
117
+ @scenario_report.scenario_power_distribution_cost.outputs = out
118
+
119
+ # VIOLATION SUMMARY
120
+
121
+ vio = []
122
+ # read result from JSON report
123
+ vio = @disco_json_results['violation_summary']
124
+ @scenario_report.scenario_power_distribution_cost.violation_summary = vio
125
+
126
+ # COSTS PER EQUIPMENT
127
+ cos = []
128
+ # read result from JSON report
129
+ cos = @disco_json_results['costs_per_equipment']
130
+ @scenario_report.scenario_power_distribution_cost.costs_per_equipment = cos
131
+
132
+ # EQUIPMENT
133
+ equ = []
134
+ # read result from JSON report
135
+ equ = @disco_json_results['equipment']
136
+ @scenario_report.scenario_power_distribution_cost.equipment = equ
137
+
138
+ end
139
+
140
+ ##
141
+ # run disco post_processor
142
+ ##
143
+ def run
144
+
145
+ # load data
146
+ load_data
147
+
148
+ # save additional global disco fields
149
+ save_disco_scenario
150
+
151
+ # save the updated scenario reports
152
+ # set save_feature_reports to false since only the scenario reports should be saved
153
+ # now, set save csv reports to false
154
+ @scenario_report.save(file_name = 'scenario_report_disco', save_feature_reports = false, save_csv_reports = false)
155
+ end
156
+
157
+ end
158
+ end
159
+ end
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -71,6 +71,9 @@ module URBANopt
71
71
  # initialize feature_reports data
72
72
  @feature_reports_data = {}
73
73
 
74
+ # initialize opendss json results
75
+ @opendss_json_results = {}
76
+
74
77
  # initialize logger
75
78
  @@logger ||= URBANopt::Reporting::DefaultReports.logger
76
79
  end
@@ -85,6 +88,12 @@ module URBANopt
85
88
  @opendss_data[feature_report.id] = opendss_csv
86
89
  end
87
90
 
91
+ # load Model.json results (if exists)
92
+ opendss_json_filename = File.join(@opendss_results_dir, 'json_files', 'Model.json')
93
+ if File.exist?(opendss_json_filename)
94
+ @opendss_json_results = JSON.parse(File.read(opendss_json_filename))
95
+ end
96
+
88
97
  ## load transformers data
89
98
 
90
99
  # transformers results directory path
@@ -140,11 +149,46 @@ module URBANopt
140
149
  return output
141
150
  end
142
151
 
152
+ # computer transformer results
153
+ def compute_transformer_results
154
+ # using values from opendss Model.json
155
+ results = {}
156
+ # retrieve all transformers
157
+ trsfmrs = @opendss_json_results['model'].select { |d| d['class'] == 'PowerTransformer' }
158
+ trsfmrs.each do |item|
159
+ t = { 'nominal_capacity': nil, 'reactance_resistance_ratio': nil }
160
+ name = item['name']['value']
161
+
162
+ # nominal capacity in kVA (Model.json stores it in VA)
163
+ # TODO: assuming that all windings would have the same rated power, so grabbing first one
164
+ begin
165
+ t['nominal_capacity'] = item['windings']['value'][0]['rated_power']['value'] / 1000
166
+ rescue StandardError
167
+ end
168
+
169
+ # reactance to resistance ratio:
170
+ begin
171
+ # TODO: grabbing the first one for now. Handle when there are multiple reactances and winding resistances
172
+ reactance = item['reactances']['value'][0]['value']
173
+ resistance = item['windings']['value'][0]['resistance']['value']
174
+
175
+ t['reactance_resistance_ratio'] = reactance / resistance
176
+ rescue StandardError
177
+ end
178
+
179
+ results[name] = t
180
+ end
181
+
182
+ return results
183
+ end
184
+
143
185
  # add feature reports for transformers
144
186
  def save_transformers_reports
187
+ t_res = compute_transformer_results
188
+
145
189
  @opendss_data.each_key do |k|
146
190
  if k.include? 'Transformer'
147
-
191
+ t_key = k.sub('Transformer.', '')
148
192
  # create transformer directory
149
193
  transformer_dir = File.join(@scenario_report.directory_name, k)
150
194
  FileUtils.mkdir_p(File.join(transformer_dir, 'feature_reports'))
@@ -153,6 +197,13 @@ module URBANopt
153
197
  # store under voltages and over voltages
154
198
  under_voltage_hrs = 0
155
199
  over_voltage_hrs = 0
200
+ nominal_capacity = nil
201
+ r_r_ratio = nil
202
+ begin
203
+ nominal_capacity = t_res[t_key]['nominal_capacity']
204
+ r_r_ratio = t_res[t_key]['reactance_resistance_ratio']
205
+ rescue StandardError
206
+ end
156
207
 
157
208
  transformer_csv = CSV.generate do |csv|
158
209
  @opendss_data[k].each_with_index do |row, i|
@@ -178,9 +229,11 @@ module URBANopt
178
229
  timesteps_per_hour: @scenario_report.timesteps_per_hour,
179
230
  simulation_status: 'complete')
180
231
 
181
- # assign results to transfomrer report
232
+ # assign results to transformer report
182
233
  transformer_report.power_distribution.over_voltage_hours = over_voltage_hrs
183
234
  transformer_report.power_distribution.under_voltage_hours = under_voltage_hrs
235
+ transformer_report.power_distribution.nominal_capacity = nominal_capacity
236
+ transformer_report.power_distribution.reactance_resistance_ratio = r_r_ratio
184
237
 
185
238
  ## save transformer JSON file
186
239
  # transformer_hash
@@ -226,6 +279,9 @@ module URBANopt
226
279
  def add_summary_results(feature_report)
227
280
  under_voltage_hrs = 0
228
281
  over_voltage_hrs = 0
282
+ kw = nil
283
+ kvar = nil
284
+ nominal_voltage = nil
229
285
 
230
286
  id = feature_report.id
231
287
  @opendss_data[id].each_with_index do |row, i|
@@ -242,13 +298,109 @@ module URBANopt
242
298
  end
243
299
  end
244
300
 
301
+ # also add additional keys for OpenDSS Loads
302
+ loads = @opendss_json_results['model'].select { |d| d['class'] == 'Load' }
303
+ if loads
304
+ bld_load = loads.select { |d| d['name']['value'] == id }
305
+ if bld_load
306
+ if bld_load.is_a?(Array)
307
+ bld_load = bld_load[0]
308
+ end
309
+ kw = 0
310
+ kvar = 0
311
+ # nominal_voltage (V)
312
+ nominal_voltage = bld_load['nominal_voltage']['value']
313
+ if nominal_voltage < 300
314
+ nominal_voltage *= Math.sqrt(3)
315
+ end
316
+ nominal_voltage = nominal_voltage
317
+
318
+ # max_power_kw
319
+ # max_reactive_power_kvar
320
+ pls = bld_load['phase_loads']['value']
321
+ pls.each do |pl|
322
+ kw += pl['p']['value']
323
+ kvar += pl['q']['value']
324
+ end
325
+
326
+ kw /= 1000
327
+ kvar /= 1000
328
+ else
329
+ @@logger.info("No load matching id #{id} found in OpenDSS Model.json results")
330
+ end
331
+ else
332
+ @@logger.info('No loads information found in OpenDSS Model.json results file')
333
+ end
245
334
  # assign results to feature report
246
335
  feature_report.power_distribution.over_voltage_hours = over_voltage_hrs
247
336
  feature_report.power_distribution.under_voltage_hours = under_voltage_hrs
337
+ feature_report.power_distribution.nominal_voltage = nominal_voltage
338
+ feature_report.power_distribution.max_power_kw = kw
339
+ feature_report.power_distribution.max_reactive_power_kvar = kvar
248
340
 
249
341
  return feature_report
250
342
  end
251
343
 
344
+ ##
345
+ # save opendss scenario fields
346
+ ##
347
+ def save_opendss_scenario
348
+ @scenario_report.scenario_power_distribution = URBANopt::Reporting::DefaultReports::ScenarioPowerDistribution.new
349
+
350
+ ## SUBSTATION
351
+ subs = []
352
+ feeders = @opendss_json_results['model'].select { |d| d['class'] == 'Feeder_metadata' }
353
+
354
+ feeders.each do |item|
355
+ # nominal_voltage - RMS voltage low side (V)
356
+ substation = { nominal_voltage: item['nominal_voltage']['value'] }
357
+ subs.append(substation)
358
+ end
359
+ @scenario_report.scenario_power_distribution.substations = subs
360
+
361
+ ## LINES
362
+ # retrieve all lines
363
+ dist_lines = []
364
+ lines = @opendss_json_results['model'].select { |d| d['class'] == 'Line' }
365
+ lines.each do |item|
366
+ line = {}
367
+ # length (m)
368
+ line['length'] = item['length']['value']
369
+
370
+ # max ampacity: iterate through N-1 wires and add up ampacity
371
+ amps = 0
372
+ num_wires = item['wires']['value'].length
373
+ (0..(num_wires - 1)).each do |i|
374
+ amps += item['wires']['value'][i]['ampacity']['value']
375
+ end
376
+ line['ampacity'] = amps
377
+
378
+ # commercial line type
379
+ line['commercial_line_type'] = []
380
+ item['wires']['value'].each do |wire|
381
+ line['commercial_line_type'].append(wire['nameclass']['value'])
382
+ end
383
+ dist_lines.append(line)
384
+ end
385
+ @scenario_report.scenario_power_distribution.distribution_lines = dist_lines
386
+
387
+ # CAPACITORS
388
+ caps = []
389
+ capacitors = @opendss_json_results['model'].select { |d| d['class'] == 'Capacitors' }
390
+ capacitors.each do |item|
391
+ cap = 0
392
+ item['phase_capacitors']['value'].each do |pc|
393
+ if pc['var']['value']
394
+ cap += pc['var']['value']
395
+ end
396
+ end
397
+ caps.append({ nominal_capacity: cap })
398
+ end
399
+ @scenario_report.scenario_power_distribution.capacitors = caps
400
+ end
401
+
402
+
403
+
252
404
  ##
253
405
  # run opendss post_processor
254
406
  ##
@@ -266,7 +418,7 @@ module URBANopt
266
418
  id = feature_report.id
267
419
  updated_feature_csv = merge_data(@feature_reports_data[id], @opendss_data[id])
268
420
 
269
- # save fetaure reports
421
+ # save feature reports
270
422
  feature_report.save_json_report('default_feature_report_opendss')
271
423
 
272
424
  # resave updated csv report
@@ -276,6 +428,9 @@ module URBANopt
276
428
  # add transformer reports
277
429
  save_transformers_reports
278
430
 
431
+ # save additional global opendss fields
432
+ save_opendss_scenario
433
+
279
434
  # save the updated scenario reports
280
435
  # set save_feature_reports to false since only the scenario reports should be saved now
281
436
  @scenario_report.save(file_name = 'scenario_report_opendss', save_feature_reports = false)
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -45,10 +45,11 @@ require 'json'
45
45
  module URBANopt
46
46
  module Scenario
47
47
  class ResultVisualization
48
- def self.create_visualization(run_dir, feature = true, feature_names = false)
48
+ def self.create_visualization(default_report_list, feature = true, feature_names = false)
49
49
  @all_results = []
50
50
  name = nil
51
- run_dir.each do |folder|
51
+
52
+ default_report_list.each do |folder|
52
53
  # create visualization for scenarios
53
54
  case feature
54
55
  when false
@@ -57,11 +58,14 @@ module URBANopt
57
58
 
58
59
  # create visualization for features
59
60
  when true
60
- index = run_dir.index(folder)
61
+ index = default_report_list.index(folder)
61
62
  name = "#{folder.split('/')[-3]}-#{feature_names[index]}"
62
63
  csv_dir = folder
63
64
  end
64
65
 
66
+ # get JSON report
67
+ json_report = folder.gsub('.csv', '.json')
68
+
65
69
  if File.exist?(csv_dir)
66
70
  size = CSV.open(csv_dir).readlines.size
67
71
 
@@ -210,6 +214,7 @@ module URBANopt
210
214
  results['name'] = name
211
215
  results['monthly_values'] = {}
212
216
  results['annual_values'] = {}
217
+ results['qaqc_flags'] = {}
213
218
 
214
219
  if @jan_next_year_index.nil? || @feb_index.nil? || @mar_index.nil? || @apr_index.nil? || @may_index.nil? || @jun_index.nil? || @jul_index.nil? || @aug_index.nil? || @sep_index.nil? || @oct_index.nil? || @nov_index.nil? || @dec_index.nil?
215
220
  results['complete_simulation'] = false
@@ -230,6 +235,18 @@ module URBANopt
230
235
  end
231
236
  end
232
237
 
238
+ # QAQC flags by category (if present)
239
+ if File.exist?(json_report)
240
+ report_data = JSON.parse(File.read(json_report))
241
+ if feature == false
242
+ # adjust nesting for scenario report
243
+ report_data = report_data['scenario_report']
244
+ end
245
+
246
+ if report_data.key?('qaqc_flags')
247
+ results['qaqc_flags'] = report_data['qaqc_flags']
248
+ end
249
+ end
233
250
  end
234
251
 
235
252
  unless results.nil?
@@ -237,13 +254,13 @@ module URBANopt
237
254
  end
238
255
  end
239
256
 
240
- # create json with required data stored in a variable
257
+ # create js file with required data stored in a variable
241
258
  if feature == false
242
259
  # In case of scenario visualization store result at top of the run folder
243
- results_path = File.expand_path('../../scenarioData.js', run_dir[0])
260
+ results_path = File.expand_path('../../scenarioData.js', default_report_list[0])
244
261
  else
245
262
  # In case of feature visualization store result at top of scenario folder folder
246
- results_path = File.expand_path('../../../scenarioData.js', run_dir[0])
263
+ results_path = File.expand_path('../../../scenarioData.js', default_report_list[0])
247
264
  end
248
265
  File.open(results_path, 'w') do |file|
249
266
  file << "var scenarioData = #{JSON.pretty_generate(@all_results)};"
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -174,9 +174,6 @@ module URBANopt
174
174
  # depends on the feature file
175
175
  dependencies << scenario.feature_file.path
176
176
 
177
- # depends on the csv file
178
- dependencies << scenario.csv_file
179
-
180
177
  # depends on the mapper classes
181
178
  Dir.glob(File.join(scenario.mapper_files_dir, '*')).each do |f|
182
179
  dependencies << f
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -40,6 +40,6 @@
40
40
 
41
41
  module URBANopt
42
42
  module Scenario
43
- VERSION = '0.7.0'.freeze
43
+ VERSION = '0.9.0'.freeze
44
44
  end
45
45
  end
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -47,6 +47,7 @@ require 'urbanopt/scenario/scenario_csv'
47
47
  require 'urbanopt/scenario/scenario_post_processor_base'
48
48
  require 'urbanopt/scenario/scenario_post_processor_default'
49
49
  require 'urbanopt/scenario/scenario_post_processor_opendss'
50
+ require 'urbanopt/scenario/scenario_post_processor_disco'
50
51
  require 'urbanopt/scenario/scenario_runner_base'
51
52
  require 'urbanopt/scenario/scenario_runner_osw'
52
53
  require 'urbanopt/scenario/simulation_dir_base'
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,