urbanopt-scenario 0.2.0.pre1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/pull_request_template.md +2 -2
- data/.gitignore +2 -0
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +77 -1
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +28 -18
- data/Jenkinsfile +1 -1
- data/LICENSE.md +1 -1
- data/RDOC_MAIN.md +1 -1
- data/README.md +1 -1
- data/Rakefile +2 -2
- data/docs/README.md +1 -1
- data/docs/package-lock.json +2499 -2322
- data/docs/package.json +13 -9
- data/lib/urbanopt-scenario.rb +1 -1
- data/lib/urbanopt/scenario.rb +3 -1
- data/lib/urbanopt/scenario/default_reports.rb +3 -8
- data/lib/urbanopt/scenario/extension.rb +1 -1
- data/lib/urbanopt/scenario/logger.rb +1 -1
- data/lib/urbanopt/scenario/scenario_base.rb +1 -1
- data/lib/urbanopt/scenario/scenario_csv.rb +22 -9
- data/lib/urbanopt/scenario/scenario_datapoint_base.rb +8 -1
- data/lib/urbanopt/scenario/scenario_post_processor_base.rb +1 -1
- data/lib/urbanopt/scenario/scenario_post_processor_default.rb +81 -8
- data/lib/urbanopt/scenario/scenario_post_processor_opendss.rb +275 -0
- data/lib/urbanopt/scenario/scenario_runner_base.rb +2 -2
- data/lib/urbanopt/scenario/scenario_runner_osw.rb +23 -9
- data/lib/urbanopt/scenario/scenario_visualization.rb +236 -0
- data/lib/urbanopt/scenario/simulation_dir_base.rb +1 -1
- data/lib/urbanopt/scenario/simulation_dir_osw.rb +2 -9
- data/lib/urbanopt/scenario/simulation_mapper_base.rb +1 -1
- data/lib/urbanopt/scenario/version.rb +2 -2
- data/package-lock.json +3 -0
- data/urbanopt-scenario-gem.gemspec +15 -15
- metadata +78 -82
- data/doc_templates/LICENSE.md +0 -27
- data/doc_templates/README.md.erb +0 -42
- data/doc_templates/copyright_erb.txt +0 -31
- data/doc_templates/copyright_js.txt +0 -4
- data/doc_templates/copyright_ruby.txt +0 -29
- data/lib/change_log.rb +0 -147
- data/lib/measures/.rubocop.yml +0 -5
- data/lib/measures/default_feature_reports/LICENSE.md +0 -27
- data/lib/measures/default_feature_reports/README.md +0 -56
- data/lib/measures/default_feature_reports/README.md.erb +0 -42
- data/lib/measures/default_feature_reports/measure.rb +0 -957
- data/lib/measures/default_feature_reports/measure.xml +0 -143
- data/lib/measures/default_feature_reports/tests/USA_CO_Golden-NREL.724666_TMY3.epw +0 -8768
- data/lib/measures/default_feature_reports/tests/default_feature_reports_test.rb +0 -238
- data/lib/measures/default_feature_reports/tests/example_model.osm +0 -4378
- data/lib/urbanopt/scenario/default_reports/construction_cost.rb +0 -169
- data/lib/urbanopt/scenario/default_reports/date.rb +0 -97
- data/lib/urbanopt/scenario/default_reports/distributed_generation.rb +0 -374
- data/lib/urbanopt/scenario/default_reports/end_use.rb +0 -159
- data/lib/urbanopt/scenario/default_reports/end_uses.rb +0 -140
- data/lib/urbanopt/scenario/default_reports/feature_report.rb +0 -260
- data/lib/urbanopt/scenario/default_reports/generator.rb +0 -92
- data/lib/urbanopt/scenario/default_reports/location.rb +0 -99
- data/lib/urbanopt/scenario/default_reports/logger.rb +0 -44
- data/lib/urbanopt/scenario/default_reports/program.rb +0 -266
- data/lib/urbanopt/scenario/default_reports/reporting_period.rb +0 -301
- data/lib/urbanopt/scenario/default_reports/scenario_report.rb +0 -311
- data/lib/urbanopt/scenario/default_reports/schema/README.md +0 -33
- data/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt +0 -21
- data/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json +0 -839
- data/lib/urbanopt/scenario/default_reports/solar_pv.rb +0 -93
- data/lib/urbanopt/scenario/default_reports/storage.rb +0 -105
- data/lib/urbanopt/scenario/default_reports/timeseries_csv.rb +0 -284
- data/lib/urbanopt/scenario/default_reports/validator.rb +0 -97
- 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,260 +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/validator'
|
37
|
-
require 'urbanopt/scenario/default_reports/distributed_generation'
|
38
|
-
|
39
|
-
require 'json-schema'
|
40
|
-
|
41
|
-
require 'json'
|
42
|
-
|
43
|
-
module URBANopt
|
44
|
-
module Scenario
|
45
|
-
module DefaultReports
|
46
|
-
##
|
47
|
-
# FeatureReport generates two types of reports in a simulation_dir.
|
48
|
-
# The default_feature_reports measure writes a 'default_feature_reports.json' file containing
|
49
|
-
# information on all features in the simulation. It also writes a 'default_feature_reports.csv'
|
50
|
-
# containing timeseries data for all features in the simulation.
|
51
|
-
# The DefaultPostProcessor reads these feature reports and aggregates them to create a ScenarioReport.
|
52
|
-
##
|
53
|
-
class FeatureReport
|
54
|
-
attr_accessor :id, :name, :directory_name, :feature_type, :timesteps_per_hour, :simulation_status,
|
55
|
-
:timeseries_csv, :location, :program, :design_parameters, :construction_costs, :reporting_periods, :distributed_generation # :nodoc:
|
56
|
-
##
|
57
|
-
# Each FeatureReport object corresponds to a single Feature.
|
58
|
-
##
|
59
|
-
# [parameters:]
|
60
|
-
# +hash+ - _Hash_ - A hash which may contain a deserialized feature_report.
|
61
|
-
##
|
62
|
-
def initialize(hash = {})
|
63
|
-
hash.delete_if { |k, v| v.nil? }
|
64
|
-
hash = defaults.merge(hash)
|
65
|
-
|
66
|
-
@id = hash[:id]
|
67
|
-
@name = hash[:name]
|
68
|
-
@directory_name = hash[:directory_name]
|
69
|
-
@feature_type = hash[:feature_type]
|
70
|
-
@timesteps_per_hour = hash[:timesteps_per_hour]
|
71
|
-
@simulation_status = hash[:simulation_status]
|
72
|
-
@timeseries_csv = TimeseriesCSV.new(hash[:timeseries_csv])
|
73
|
-
@timeseries_csv.run_dir_name(@directory_name)
|
74
|
-
@location = Location.new(hash[:location])
|
75
|
-
@program = Program.new(hash[:program])
|
76
|
-
# design_parameters to add later
|
77
|
-
@construction_costs = []
|
78
|
-
hash[:construction_costs].each do |cc|
|
79
|
-
@constructiion_costs << ConstructionCost.new(cc)
|
80
|
-
end
|
81
|
-
|
82
|
-
@reporting_periods = []
|
83
|
-
hash[:reporting_periods].each do |rp|
|
84
|
-
@reporting_periods << ReportingPeriod.new(rp)
|
85
|
-
end
|
86
|
-
|
87
|
-
@distributed_generation = DistributedGeneration.new(hash[:distributed_generation] || {})
|
88
|
-
|
89
|
-
# initialize class variables @@validator and @@schema
|
90
|
-
@@validator ||= Validator.new
|
91
|
-
@@schema ||= @@validator.schema
|
92
|
-
|
93
|
-
# initialize feature report file name to be saved.
|
94
|
-
@file_name = 'default_feature_report'
|
95
|
-
end
|
96
|
-
|
97
|
-
##
|
98
|
-
# Assign default values if values does not exist.
|
99
|
-
##
|
100
|
-
def defaults
|
101
|
-
hash = {}
|
102
|
-
hash[:timeseries_csv] = {}
|
103
|
-
hash[:location] = {}
|
104
|
-
hash[:program] = {}
|
105
|
-
hash[:construction_costs] = []
|
106
|
-
hash[:reporting_periods] = []
|
107
|
-
return hash
|
108
|
-
end
|
109
|
-
|
110
|
-
##
|
111
|
-
# Return an Array of FeatureReports for the simulation_dir as multiple Features can be simulated together in a single simulation directory.
|
112
|
-
##
|
113
|
-
# - Ensure that +simulation_dir+ include only one feature.
|
114
|
-
# - Read in the reports written by measure if they exist.
|
115
|
-
##
|
116
|
-
# [parameters:]
|
117
|
-
# +simulation_dir+ - _SimulationDirOSW_ - A simulation directory from an OSW simulation, must include 'default_feature_reports' measure.
|
118
|
-
##
|
119
|
-
def self.from_simulation_dir(simulation_dir)
|
120
|
-
result = []
|
121
|
-
|
122
|
-
# simulation dir can include only one feature
|
123
|
-
features = simulation_dir.features
|
124
|
-
if features.size != 1
|
125
|
-
raise 'FeatureReport cannot support multiple features per OSW'
|
126
|
-
end
|
127
|
-
|
128
|
-
# read in the reports written by measure
|
129
|
-
default_feature_reports_json = nil
|
130
|
-
default_feature_reports_csv = nil
|
131
|
-
|
132
|
-
simulation_status = simulation_dir.simulation_status
|
133
|
-
if simulation_status == 'Complete' || simulation_status == 'Failed'
|
134
|
-
|
135
|
-
# read in the scenario reports JSON and CSV
|
136
|
-
Dir.glob(File.join(simulation_dir.run_dir, '*_default_feature_reports/')).each do |dir|
|
137
|
-
scenario_reports_json_path = File.join(dir, 'default_feature_reports.json')
|
138
|
-
if File.exist?(scenario_reports_json_path)
|
139
|
-
File.open(scenario_reports_json_path, 'r') do |file|
|
140
|
-
default_feature_reports_json = JSON.parse(file.read, symbolize_names: true)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
scenario_reports_csv_path = File.join(dir, 'default_feature_reports.csv')
|
144
|
-
if File.exist?(scenario_reports_csv_path)
|
145
|
-
default_feature_reports_csv = scenario_reports_csv_path
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
end
|
150
|
-
|
151
|
-
# if we loaded the json
|
152
|
-
if default_feature_reports_json # && default_feature_reports_json[:feature_reports]
|
153
|
-
# default_feature_reports_json.each do |feature_report|
|
154
|
-
# result << FeatureReport.new(feature_report)
|
155
|
-
# end
|
156
|
-
result << FeatureReport.new(default_feature_reports_json) # should we keep it as an array !? or each each report can only include 1 feature
|
157
|
-
|
158
|
-
else
|
159
|
-
# we did not find a report
|
160
|
-
features.each do |feature|
|
161
|
-
hash = {}
|
162
|
-
hash[:id] = feature.id
|
163
|
-
hash[:name] = feature.name
|
164
|
-
hash[:directory_name] = simulation_dir.run_dir
|
165
|
-
hash[:simulation_status] = simulation_status
|
166
|
-
result << FeatureReport.new(hash)
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
# validate feature_report json against schema
|
171
|
-
if @@validator.validate(@@schema[:definitions][:FeatureReport][:properties], default_feature_reports_json).any?
|
172
|
-
raise "default_feature_report_json properties does not match schema: #{@@validator.validate(@@schema[:definitions][:FeatureReport][:properties], default_feature_reports_json)}"
|
173
|
-
end
|
174
|
-
|
175
|
-
return result
|
176
|
-
end
|
177
|
-
|
178
|
-
##
|
179
|
-
# Convert to a Hash equivalent for JSON serialization
|
180
|
-
##
|
181
|
-
# - Exclude attributes with nil values.
|
182
|
-
# - Validate feature_report hash properties against schema.
|
183
|
-
##
|
184
|
-
def to_hash
|
185
|
-
result = {}
|
186
|
-
result[:id] = @id if @id
|
187
|
-
result[:name] = @name if @name
|
188
|
-
result[:directory_name] = @directory_name if @directory_name
|
189
|
-
result[:feature_type] = @feature_type if @feature_type
|
190
|
-
result[:timesteps_per_hour] = @timesteps_per_hour if @timesteps_per_hour
|
191
|
-
result[:simulation_status] = @simulation_status if @simulation_status
|
192
|
-
result[:timeseries_csv] = @timeseries_csv.to_hash
|
193
|
-
|
194
|
-
result[:location] = @location.to_hash if @location
|
195
|
-
|
196
|
-
result[:program] = @program.to_hash
|
197
|
-
|
198
|
-
result[:construction_costs] = []
|
199
|
-
@construction_costs.each { |cc| result[:construction_costs] << cc.to_hash }
|
200
|
-
|
201
|
-
result[:reporting_periods] = []
|
202
|
-
@reporting_periods.each { |rp| result[:reporting_periods] << rp.to_hash }
|
203
|
-
|
204
|
-
result[:distributed_generation] = @distributed_generation.to_hash if @distributed_generation
|
205
|
-
|
206
|
-
# validate feature_report properties against schema
|
207
|
-
if @@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result).any?
|
208
|
-
raise "feature_report properties does not match schema: #{@@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result)}"
|
209
|
-
end
|
210
|
-
|
211
|
-
return result
|
212
|
-
end
|
213
|
-
|
214
|
-
##
|
215
|
-
# Saves the 'default_feature_report.json' and 'default_feature_report.csv' files
|
216
|
-
##
|
217
|
-
# [parameters]:
|
218
|
-
# +file_name+ - _String_ - Assign a name to the saved feature report results file without an extension
|
219
|
-
def save_feature_report(file_name = 'updated_default_feature_report')
|
220
|
-
# reassign the initialize local variable @file_name to the file name input.
|
221
|
-
@file_name = file_name
|
222
|
-
|
223
|
-
# create feature reports directory
|
224
|
-
Dir.mkdir(File.join(@directory_name, 'feature_reports')) unless Dir.exist?(File.join(@directory_name, 'feature_reports'))
|
225
|
-
|
226
|
-
# save the csv data
|
227
|
-
old_timeseries_path = nil
|
228
|
-
if !@timeseries_csv.path.nil?
|
229
|
-
old_timeseries_path = @timeseries_csv.path
|
230
|
-
end
|
231
|
-
|
232
|
-
@timeseries_csv.path = File.join(@directory_name, 'feature_reports', file_name + '.csv')
|
233
|
-
@timeseries_csv.save_data
|
234
|
-
|
235
|
-
hash = {}
|
236
|
-
hash[:feature_report] = to_hash
|
237
|
-
|
238
|
-
json_name_path = File.join(@directory_name, 'feature_reports', file_name + '.json')
|
239
|
-
|
240
|
-
File.open(json_name_path, 'w') do |f|
|
241
|
-
f.puts JSON.pretty_generate(hash)
|
242
|
-
# make sure data is written to the disk one way or the other
|
243
|
-
begin
|
244
|
-
f.fsync
|
245
|
-
rescue StandardError
|
246
|
-
f.flush
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
if !old_timeseries_path.nil?
|
251
|
-
@timeseries_csv.path = old_timeseries_path
|
252
|
-
else
|
253
|
-
@timeseries_csv.path = File.join(@directory_name, 'feature_reports', file_name + '.csv')
|
254
|
-
end
|
255
|
-
return true
|
256
|
-
end
|
257
|
-
end
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end
|