urbanopt-scenario 0.3.0.pre1 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.github/pull_request_template.md +3 -3
  3. data/.gitignore +2 -0
  4. data/CHANGELOG.md +60 -2
  5. data/CONTRIBUTING.md +1 -1
  6. data/Gemfile +33 -17
  7. data/Jenkinsfile +1 -1
  8. data/LICENSE.md +1 -1
  9. data/RDOC_MAIN.md +2 -2
  10. data/README.md +1 -1
  11. data/Rakefile +1 -1
  12. data/docs/.vuepress/components/InnerJsonSchema.vue +7 -15
  13. data/docs/.vuepress/config.js +13 -9
  14. data/docs/.vuepress/highlight.js +1 -1
  15. data/docs/.vuepress/json-schema-deref-loader.js +22 -0
  16. data/docs/README.md +2 -2
  17. data/docs/package-lock.json +2384 -2323
  18. data/docs/package.json +12 -8
  19. data/lib/urbanopt-scenario.rb +1 -1
  20. data/lib/urbanopt/scenario.rb +2 -1
  21. data/lib/urbanopt/scenario/default_reports.rb +3 -8
  22. data/lib/urbanopt/scenario/extension.rb +6 -4
  23. data/lib/urbanopt/scenario/logger.rb +1 -1
  24. data/lib/urbanopt/scenario/scenario_base.rb +5 -5
  25. data/lib/urbanopt/scenario/scenario_csv.rb +29 -17
  26. data/lib/urbanopt/scenario/scenario_datapoint_base.rb +12 -5
  27. data/lib/urbanopt/scenario/scenario_post_processor_base.rb +3 -3
  28. data/lib/urbanopt/scenario/scenario_post_processor_default.rb +121 -11
  29. data/lib/urbanopt/scenario/scenario_post_processor_opendss.rb +13 -14
  30. data/lib/urbanopt/scenario/scenario_runner_base.rb +8 -7
  31. data/lib/urbanopt/scenario/scenario_runner_osw.rb +29 -13
  32. data/lib/urbanopt/scenario/scenario_visualization.rb +235 -0
  33. data/lib/urbanopt/scenario/simulation_dir_base.rb +4 -4
  34. data/lib/urbanopt/scenario/simulation_dir_osw.rb +6 -13
  35. data/lib/urbanopt/scenario/simulation_mapper_base.rb +4 -4
  36. data/lib/urbanopt/scenario/version.rb +2 -2
  37. data/package-lock.json +3 -0
  38. data/urbanopt-scenario-gem.gemspec +11 -10
  39. metadata +80 -57
  40. data/doc_templates/LICENSE.md +0 -27
  41. data/doc_templates/README.md.erb +0 -42
  42. data/doc_templates/copyright_erb.txt +0 -31
  43. data/doc_templates/copyright_js.txt +0 -4
  44. data/doc_templates/copyright_ruby.txt +0 -29
  45. data/docs/.vuepress/components/ScenarioSchema.vue +0 -12
  46. data/docs/schemas/scenario-schema.md +0 -3
  47. data/lib/measures/.rubocop.yml +0 -5
  48. data/lib/measures/default_feature_reports/LICENSE.md +0 -27
  49. data/lib/measures/default_feature_reports/README.md +0 -56
  50. data/lib/measures/default_feature_reports/README.md.erb +0 -42
  51. data/lib/measures/default_feature_reports/measure.rb +0 -1006
  52. data/lib/measures/default_feature_reports/measure.xml +0 -143
  53. data/lib/measures/default_feature_reports/tests/USA_CO_Golden-NREL.724666_TMY3.epw +0 -8768
  54. data/lib/measures/default_feature_reports/tests/default_feature_reports_test.rb +0 -238
  55. data/lib/measures/default_feature_reports/tests/example_model.osm +0 -4378
  56. data/lib/urbanopt/scenario/default_reports/construction_cost.rb +0 -169
  57. data/lib/urbanopt/scenario/default_reports/date.rb +0 -97
  58. data/lib/urbanopt/scenario/default_reports/distributed_generation.rb +0 -379
  59. data/lib/urbanopt/scenario/default_reports/end_use.rb +0 -159
  60. data/lib/urbanopt/scenario/default_reports/end_uses.rb +0 -140
  61. data/lib/urbanopt/scenario/default_reports/feature_report.rb +0 -267
  62. data/lib/urbanopt/scenario/default_reports/generator.rb +0 -92
  63. data/lib/urbanopt/scenario/default_reports/location.rb +0 -99
  64. data/lib/urbanopt/scenario/default_reports/logger.rb +0 -44
  65. data/lib/urbanopt/scenario/default_reports/power_distribution.rb +0 -102
  66. data/lib/urbanopt/scenario/default_reports/program.rb +0 -266
  67. data/lib/urbanopt/scenario/default_reports/reporting_period.rb +0 -305
  68. data/lib/urbanopt/scenario/default_reports/scenario_report.rb +0 -317
  69. data/lib/urbanopt/scenario/default_reports/schema/README.md +0 -33
  70. data/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt +0 -32
  71. data/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json +0 -857
  72. data/lib/urbanopt/scenario/default_reports/solar_pv.rb +0 -93
  73. data/lib/urbanopt/scenario/default_reports/storage.rb +0 -105
  74. data/lib/urbanopt/scenario/default_reports/timeseries_csv.rb +0 -299
  75. data/lib/urbanopt/scenario/default_reports/validator.rb +0 -97
  76. data/lib/urbanopt/scenario/default_reports/wind.rb +0 -92
@@ -1,159 +0,0 @@
1
- # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019-2020, 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
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
- # OF THE POSSIBILITY OF SUCH DAMAGE.
29
- # *********************************************************************************
30
-
31
- require 'urbanopt/scenario/default_reports/validator'
32
- require 'json-schema'
33
-
34
- module URBANopt
35
- module Scenario
36
- module DefaultReports
37
- ##
38
- # Enduse class all enduse energy consumption results.
39
- ##
40
- class EndUse
41
- attr_accessor :heating, :cooling, :interior_lighting, :exterior_lighting, :interior_equipment, :exterior_equipment,
42
- :fans, :pumps, :heat_rejection, :humidification, :heat_recovery, :water_systems, :refrigeration, :generators # :nodoc:
43
-
44
- ##
45
- # EndUse class intialize all enduse atributes: +:heating+ , +:cooling+ , +:interior_lighting+ ,
46
- # +:exterior_lighting+ , +:interior_equipment+ , +:exterior_equipment+ ,
47
- # +:fans+ , +:pumps+ , +:heat_rejection+ , +:humidification+ , +:heat_recovery+ , +:water_systems+ , +:refrigeration+ , +:generators+
48
- ##
49
- # [parameters:]
50
- # +hash+ - _Hash_ - A hash which may contain a deserialized end_use.
51
- ##
52
- def initialize(hash = {})
53
- hash.delete_if { |k, v| v.nil? }
54
- hash = defaults.merge(hash)
55
-
56
- @heating = hash[:heating]
57
- @cooling = hash[:cooling]
58
- @interior_lighting = hash[:interior_lighting]
59
- @exterior_lighting = hash[:exterior_lighting]
60
- @interior_equipment = hash[:interior_equipment]
61
- @exterior_equipment = hash[:exterior_equipment]
62
- @fans = hash[:fans]
63
- @pumps = hash[:pumps]
64
- @heat_rejection = hash[:heat_rejection]
65
- @humidification = hash[:humidification]
66
- @heat_recovery = hash[:heat_recovery]
67
- @water_systems = hash[:water_systems]
68
- @refrigeration = hash[:refrigeration]
69
- @generators = hash[:generators]
70
-
71
- # initialize class variables @@validator and @@schema
72
- @@validator ||= Validator.new
73
- @@schema ||= @@validator.schema
74
- end
75
-
76
- ##
77
- # Assign default values if values does not exist
78
- ##
79
- def defaults
80
- hash = {}
81
-
82
- hash[:heating] = nil
83
- hash[:cooling] = nil
84
- hash[:interior_lighting] = nil
85
- hash[:exterior_lighting] = nil
86
- hash[:interior_equipment] = nil
87
- hash[:exterior_equipment] = nil
88
- hash[:fans] = nil
89
- hash[:pumps] = nil
90
- hash[:heat_rejection] = nil
91
- hash[:humidification] = nil
92
- hash[:heat_recovery] = nil
93
- hash[:water_systems] = nil
94
- hash[:refrigeration] = nil
95
- hash[:generators] = nil
96
-
97
- return hash
98
- end
99
-
100
- ##
101
- # Convert to a Hash equivalent for JSON serialization.
102
- ##
103
- # - Exclude attributes with nil values.
104
- # - Validate end_use hash properties against schema.
105
- ##
106
- def to_hash
107
- result = {}
108
-
109
- result[:heating] = @heating
110
- result[:cooling] = @cooling
111
- result[:interior_lighting] = @interior_lighting
112
- result[:exterior_lighting] = @exterior_lighting
113
- result[:interior_equipment] = @interior_equipment
114
- result[:exterior_equipment] = @exterior_equipment
115
- result[:fans] = @fans
116
- result[:pumps] = @pumps
117
- result[:heat_rejection] = @heat_rejection
118
- result[:humidification] = @humidification
119
- result[:heat_recovery] = @heat_recovery
120
- result[:water_systems] = @water_systems
121
- result[:refrigeration] = @refrigeration
122
- result[:generators] = @generators
123
-
124
- # validate end_use properties against schema
125
- if @@validator.validate(@@schema[:definitions][:EndUse][:properties], result).any?
126
- raise "end_use properties does not match schema: #{@@validator.validate(@@schema[:definitions][:EndUse][:properties], result)}"
127
- end
128
-
129
- return result
130
- end
131
-
132
- ##
133
- # Aggregate values of each EndUse attribute.
134
- ##
135
- # [Parameters:]
136
- # +new_end_use+ - _EndUse_ - An object of EndUse class.
137
- ##
138
- def merge_end_use!(new_end_use)
139
- @heating += new_end_use.heating if new_end_use.heating
140
- @cooling += new_end_use.cooling if new_end_use.cooling
141
- @interior_lighting += new_end_use.interior_lighting if new_end_use.interior_lighting
142
- @exterior_lighting += new_end_use.exterior_lighting if new_end_use.exterior_lighting
143
- @interior_equipment += new_end_use.interior_equipment if new_end_use.interior_equipment
144
- @exterior_equipment += new_end_use.exterior_equipment if new_end_use.exterior_equipment
145
- @fans += new_end_use.fans if new_end_use.fans
146
- @pumps += new_end_use.pumps if new_end_use.pumps
147
- @heat_rejection += new_end_use.heat_rejection if new_end_use.heat_rejection
148
- @humidification += new_end_use.humidification if new_end_use.humidification
149
- @heat_recovery += new_end_use.heat_recovery if new_end_use.heat_recovery
150
- @water_systems += new_end_use.water_systems if new_end_use.water_systems
151
- @refrigeration += new_end_use.refrigeration if new_end_use.refrigeration
152
- @generators += new_end_use.generators if new_end_use.generators
153
-
154
- return self
155
- end
156
- end
157
- end
158
- end
159
- end
@@ -1,140 +0,0 @@
1
- # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019-2020, 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
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
- # OF THE POSSIBILITY OF SUCH DAMAGE.
29
- # *********************************************************************************
30
-
31
- require 'urbanopt/scenario/default_reports/end_use'
32
- require 'urbanopt/scenario/default_reports/validator'
33
- require 'json-schema'
34
-
35
- module URBANopt
36
- module Scenario
37
- module DefaultReports
38
- ##
39
- # Enduses class inlclude results for each fuel type.
40
- ##
41
- class EndUses
42
- attr_accessor :electricity, :natural_gas, :additional_fuel, :district_cooling, :district_heating, :water # :nodoc:
43
- ##
44
- # EndUses class intialize end_uses(fuel type) attributes: +:electricity+ , +:natural_gas+ , +:additional_fuel+ ,
45
- # +:district_cooling+ , +:district_heating+ , +:water+
46
- ##
47
- # [parameters:]
48
- # +hash+ - _Hash_ - A hash which may contain a deserialized end_uses.
49
- ##
50
- def initialize(hash = {})
51
- hash.delete_if { |k, v| v.nil? }
52
- hash = defaults.merge(hash)
53
-
54
- @electricity = EndUse.new(hash[:electricity])
55
- @natural_gas = EndUse.new(hash[:natural_gas])
56
- @additional_fuel = EndUse.new(hash[:additional_fuel])
57
- @district_cooling = EndUse.new(hash[:district_cooling])
58
- @district_heating = EndUse.new(hash[:district_heating])
59
- @water = EndUse.new(hash[:water])
60
-
61
- # initialize class variables @@validator and @@schema
62
- @@validator ||= Validator.new
63
- @@schema ||= @@validator.schema
64
- end
65
-
66
- ##
67
- # Converts to a Hash equivalent for JSON serialization.
68
- ##
69
- # - Exclude attributes with nil values.
70
- # - Validate end_uses hash properties against schema.
71
- ##
72
- def to_hash
73
- result = {}
74
-
75
- electricity_hash = @electricity.to_hash if @electricity.to_hash
76
- electricity_hash.delete_if { |k, v| v.nil? }
77
- result[:electricity] = electricity_hash if @electricity
78
-
79
- natural_gas_hash = @natural_gas.to_hash if @natural_gas
80
- natural_gas_hash.delete_if { |k, v| v.nil? }
81
- result[:natural_gas] = natural_gas_hash if @natural_gas
82
-
83
- additional_fuel_hash = @additional_fuel.to_hash if @additional_fuel
84
- additional_fuel_hash.delete_if { |k, v| v.nil? }
85
- result[:additional_fuel] = additional_fuel_hash if @additional_fuel
86
-
87
- district_cooling_hash = @district_cooling.to_hash if @district_cooling
88
- district_cooling_hash.delete_if { |k, v| v.nil? }
89
- result[:district_cooling] = district_cooling_hash if @district_cooling
90
-
91
- district_heating_hash = @district_heating.to_hash if @district_heating
92
- district_heating_hash.delete_if { |k, v| v.nil? }
93
- result[:district_heating] = district_heating_hash if @district_heating
94
-
95
- water_hash = @water.to_hash if @water
96
- water_hash.delete_if { |k, v| v.nil? }
97
- result[:water] = water_hash if @water
98
-
99
- # validate end_uses properties against schema
100
- if @@validator.validate(@@schema[:definitions][:EndUses][:properties], result).any?
101
- raise "end_uses properties does not match schema: #{@@validator.validate(@@schema[:definitions][:EndUses][:properties], result)}"
102
- end
103
-
104
- return result
105
- end
106
-
107
- ##
108
- # Assigns default values if values do not exist.
109
- ##
110
- def defaults
111
- hash = {}
112
- hash[:electricity] = EndUse.new.to_hash
113
- hash[:natural_gas] = EndUse.new.to_hash
114
- hash[:additional_fuel] = EndUse.new.to_hash
115
- hash[:district_cooling] = EndUse.new.to_hash
116
- hash[:district_heating] = EndUse.new.to_hash
117
- hash[:water] = EndUse.new.to_hash
118
-
119
- return hash
120
- end
121
-
122
- ##
123
- # Aggregates the values of each EndUse attribute.
124
- ##
125
- # [Parameters:]
126
- # +new_end_uses+ - _EndUses_ - An object of EndUses class.
127
- ##
128
- def merge_end_uses!(new_end_uses)
129
- # modify the existing_period by summing up the results ; # sum results only if they exist
130
- @electricity.merge_end_use!(new_end_uses.electricity)
131
- @natural_gas.merge_end_use!(new_end_uses.natural_gas)
132
- @additional_fuel.merge_end_use!(new_end_uses.additional_fuel)
133
- @district_cooling.merge_end_use!(new_end_uses.district_cooling)
134
- @district_heating.merge_end_use!(new_end_uses.district_heating)
135
- return self
136
- end
137
- end
138
- end
139
- end
140
- end
@@ -1,267 +0,0 @@
1
- # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019-2020, 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
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
- # OF THE POSSIBILITY OF SUCH DAMAGE.
29
- # *********************************************************************************
30
-
31
- require 'urbanopt/scenario/default_reports/construction_cost'
32
- require 'urbanopt/scenario/default_reports/program'
33
- require 'urbanopt/scenario/default_reports/location'
34
- require 'urbanopt/scenario/default_reports/reporting_period'
35
- require 'urbanopt/scenario/default_reports/timeseries_csv'
36
- require 'urbanopt/scenario/default_reports/distributed_generation'
37
- require 'urbanopt/scenario/default_reports/power_distribution'
38
-
39
- require 'urbanopt/scenario/default_reports/validator'
40
- require 'json-schema'
41
-
42
- require 'json'
43
-
44
- module URBANopt
45
- module Scenario
46
- module DefaultReports
47
- ##
48
- # FeatureReport generates two types of reports in a simulation_dir.
49
- # The default_feature_reports measure writes a 'default_feature_reports.json' file containing
50
- # information on all features in the simulation. It also writes a 'default_feature_reports.csv'
51
- # containing timeseries data for all features in the simulation.
52
- # The DefaultPostProcessor reads these feature reports and aggregates them to create a ScenarioReport.
53
- ##
54
- class FeatureReport
55
- attr_accessor :id, :name, :directory_name, :feature_type, :timesteps_per_hour, :simulation_status,
56
- :timeseries_csv, :location, :program, :design_parameters, :construction_costs, :reporting_periods, :distributed_generation, :power_distribution # :nodoc:
57
- ##
58
- # Each FeatureReport object corresponds to a single Feature.
59
- ##
60
- # [parameters:]
61
- # +hash+ - _Hash_ - A hash which may contain a deserialized feature_report.
62
- ##
63
- def initialize(hash = {})
64
- hash.delete_if { |k, v| v.nil? }
65
- hash = defaults.merge(hash)
66
-
67
- @id = hash[:id]
68
- @name = hash[:name]
69
- @directory_name = hash[:directory_name]
70
- @feature_type = hash[:feature_type]
71
- @timesteps_per_hour = hash[:timesteps_per_hour]
72
- @simulation_status = hash[:simulation_status]
73
- @timeseries_csv = TimeseriesCSV.new(hash[:timeseries_csv])
74
- @timeseries_csv.run_dir_name(@directory_name)
75
- @location = Location.new(hash[:location])
76
- @program = Program.new(hash[:program])
77
- # design_parameters to add later
78
- @construction_costs = []
79
- hash[:construction_costs].each do |cc|
80
- @constructiion_costs << ConstructionCost.new(cc)
81
- end
82
-
83
- @reporting_periods = []
84
- hash[:reporting_periods].each do |rp|
85
- @reporting_periods << ReportingPeriod.new(rp)
86
- end
87
-
88
- @distributed_generation = DistributedGeneration.new(hash[:distributed_generation])
89
-
90
- @power_distribution = PowerDistribution.new(hash[:power_distribution])
91
-
92
- # initialize class variables @@validator and @@schema
93
- @@validator ||= Validator.new
94
- @@schema ||= @@validator.schema
95
-
96
- # initialize feature report file name to be saved.
97
- @file_name = 'default_feature_report'
98
- end
99
-
100
- ##
101
- # Assign default values if values does not exist.
102
- ##
103
- def defaults
104
- hash = {}
105
- hash[:timeseries_csv] = {}
106
- hash[:location] = {}
107
- hash[:program] = {}
108
- hash[:construction_costs] = []
109
- hash[:reporting_periods] = []
110
- hash[:distributed_generation] = {}
111
- hash[:power_distribution] = {}
112
- return hash
113
- end
114
-
115
- ##
116
- # Return an Array of FeatureReports for the simulation_dir as multiple Features can be simulated together in a single simulation directory.
117
- ##
118
- # - Ensure that +simulation_dir+ include only one feature.
119
- # - Read in the reports written by measure if they exist.
120
- ##
121
- # [parameters:]
122
- # +simulation_dir+ - _SimulationDirOSW_ - A simulation directory from an OSW simulation, must include 'default_feature_reports' measure.
123
- ##
124
- def self.from_simulation_dir(simulation_dir)
125
- result = []
126
-
127
- # simulation dir can include only one feature
128
- features = simulation_dir.features
129
- if features.size != 1
130
- raise 'FeatureReport cannot support multiple features per OSW'
131
- end
132
-
133
- # read in the reports written by measure
134
- default_feature_reports_json = nil
135
- default_feature_reports_csv = nil
136
-
137
- simulation_status = simulation_dir.simulation_status
138
- if simulation_status == 'Complete' || simulation_status == 'Failed'
139
-
140
- # read in the scenario reports JSON and CSV
141
- Dir.glob(File.join(simulation_dir.run_dir, '*_default_feature_reports/')).each do |dir|
142
- scenario_reports_json_path = File.join(dir, 'default_feature_reports.json')
143
- if File.exist?(scenario_reports_json_path)
144
- File.open(scenario_reports_json_path, 'r') do |file|
145
- default_feature_reports_json = JSON.parse(file.read, symbolize_names: true)
146
- end
147
- end
148
- scenario_reports_csv_path = File.join(dir, 'default_feature_reports.csv')
149
- if File.exist?(scenario_reports_csv_path)
150
- default_feature_reports_csv = scenario_reports_csv_path
151
- end
152
- end
153
-
154
- end
155
-
156
- # if we loaded the json
157
- if default_feature_reports_json # && default_feature_reports_json[:feature_reports]
158
- # default_feature_reports_json.each do |feature_report|
159
- # result << FeatureReport.new(feature_report)
160
- # end
161
- result << FeatureReport.new(default_feature_reports_json) # should we keep it as an array !? or each each report can only include 1 feature
162
-
163
- else
164
- # we did not find a report
165
- features.each do |feature|
166
- hash = {}
167
- hash[:id] = feature.id
168
- hash[:name] = feature.name
169
- hash[:directory_name] = simulation_dir.run_dir
170
- hash[:simulation_status] = simulation_status
171
- result << FeatureReport.new(hash)
172
- end
173
- end
174
-
175
- # validate feature_report json against schema
176
- if @@validator.validate(@@schema[:definitions][:FeatureReport][:properties], default_feature_reports_json).any?
177
- raise "default_feature_report_json properties does not match schema: #{@@validator.validate(@@schema[:definitions][:FeatureReport][:properties], default_feature_reports_json)}"
178
- end
179
-
180
- return result
181
- end
182
-
183
- ##
184
- # Convert to a Hash equivalent for JSON serialization
185
- ##
186
- # - Exclude attributes with nil values.
187
- # - Validate feature_report hash properties against schema.
188
- ##
189
- def to_hash
190
- result = {}
191
- result[:id] = @id if @id
192
- result[:name] = @name if @name
193
- result[:directory_name] = @directory_name if @directory_name
194
- result[:feature_type] = @feature_type if @feature_type
195
- result[:timesteps_per_hour] = @timesteps_per_hour if @timesteps_per_hour
196
- result[:simulation_status] = @simulation_status if @simulation_status
197
- result[:timeseries_csv] = @timeseries_csv.to_hash
198
-
199
- result[:location] = @location.to_hash if @location
200
-
201
- result[:program] = @program.to_hash
202
-
203
- result[:construction_costs] = []
204
- @construction_costs.each { |cc| result[:construction_costs] << cc.to_hash }
205
-
206
- result[:reporting_periods] = []
207
- @reporting_periods.each { |rp| result[:reporting_periods] << rp.to_hash }
208
-
209
- result[:distributed_generation] = @distributed_generation.to_hash if @distributed_generation
210
-
211
- result[:power_distribution] = @power_distribution.to_hash if @power_distribution
212
-
213
- # validate feature_report properties against schema
214
- if @@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result).any?
215
- raise "feature_report properties does not match schema: #{@@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result)}"
216
- end
217
-
218
- return result
219
- end
220
-
221
- ##
222
- # Saves the 'default_feature_report.json' and 'default_feature_report.csv' files
223
- ##
224
- # [parameters]:
225
- # +file_name+ - _String_ - Assign a name to the saved feature report results file without an extension
226
- def save_feature_report(file_name = 'default_feature_report')
227
- # reassign the initialize local variable @file_name to the file name input.
228
- @file_name = file_name
229
-
230
- # create feature reports directory
231
- Dir.mkdir(File.join(@directory_name, 'feature_reports')) unless Dir.exist?(File.join(@directory_name, 'feature_reports'))
232
-
233
- # save the csv data
234
- old_timeseries_path = nil
235
- if !@timeseries_csv.path.nil?
236
- old_timeseries_path = @timeseries_csv.path
237
- end
238
-
239
- @timeseries_csv.path = File.join(@directory_name, 'feature_reports', file_name + '.csv')
240
- @timeseries_csv.save_data
241
-
242
- # feature_hash
243
- feature_hash = to_hash
244
-
245
- json_name_path = File.join(@directory_name, 'feature_reports', file_name + '.json')
246
-
247
- File.open(json_name_path, 'w') do |f|
248
- f.puts JSON.pretty_generate(feature_hash)
249
- # make sure data is written to the disk one way or the other
250
- begin
251
- f.fsync
252
- rescue StandardError
253
- f.flush
254
- end
255
- end
256
-
257
- if !old_timeseries_path.nil?
258
- @timeseries_csv.path = old_timeseries_path
259
- else
260
- @timeseries_csv.path = File.join(@directory_name, 'feature_reports', file_name + '.csv')
261
- end
262
- return true
263
- end
264
- end
265
- end
266
- end
267
- end