openstudio-standards 0.8.5 → 0.8.7

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.
Files changed (174) hide show
  1. checksums.yaml +4 -4
  2. data/data/standards/test_performance_expected_dd_results.csv +90 -90
  3. data/lib/openstudio-standards/btap/activity.rb +858 -61
  4. data/lib/openstudio-standards/btap/attributes.rb +297 -103
  5. data/lib/openstudio-standards/btap/bridging.rb +1335 -593
  6. data/lib/openstudio-standards/btap/btap.rb +60 -181
  7. data/lib/openstudio-standards/btap/carbon/btap_carbon.rb +199 -142
  8. data/lib/openstudio-standards/btap/common/constructions.json +1275 -0
  9. data/lib/openstudio-standards/btap/common/costs.csv +1969 -0
  10. data/lib/openstudio-standards/btap/common/costs_local_factors.csv +2315 -0
  11. data/lib/openstudio-standards/btap/common/materials_glazing.csv +61 -0
  12. data/lib/openstudio-standards/btap/{common_resources → common}/materials_hvac.csv +1685 -1685
  13. data/lib/openstudio-standards/btap/{common_resources → common}/materials_lighting.csv +266 -266
  14. data/lib/openstudio-standards/btap/common/materials_opaque.csv +214 -0
  15. data/lib/openstudio-standards/btap/common/necb_building_types.csv +35 -0
  16. data/lib/openstudio-standards/btap/common/necb_space_types.csv +110 -0
  17. data/lib/openstudio-standards/btap/common/thermal_bridging.csv +73 -0
  18. data/lib/openstudio-standards/btap/costing/btap_costing.rb +346 -429
  19. data/lib/openstudio-standards/btap/costing/database.rb +104 -0
  20. data/lib/openstudio-standards/btap/costing/daylighting_sensor_control_costing.rb +356 -344
  21. data/lib/openstudio-standards/btap/costing/dcv_costing.rb +282 -296
  22. data/lib/openstudio-standards/btap/costing/envelope_costing.rb +179 -192
  23. data/lib/openstudio-standards/btap/costing/heating_cooling_costing.rb +2477 -2316
  24. data/lib/openstudio-standards/btap/costing/led_lighting_costing.rb +127 -142
  25. data/lib/openstudio-standards/btap/costing/lighting_costing.rb +216 -198
  26. data/lib/openstudio-standards/btap/costing/nv_costing.rb +522 -523
  27. data/lib/openstudio-standards/btap/costing/pv_ground_costing.rb +649 -649
  28. data/lib/openstudio-standards/btap/costing/shw_costing.rb +626 -625
  29. data/lib/openstudio-standards/btap/costing/thermal_bridging_costing.rb +72 -0
  30. data/lib/openstudio-standards/btap/costing/ventilation_costing.rb +2363 -2361
  31. data/lib/openstudio-standards/btap/deprecated.rb +1033 -0
  32. data/lib/openstudio-standards/btap/envelope.rb +313 -572
  33. data/lib/openstudio-standards/btap/fileio.rb +152 -1070
  34. data/lib/openstudio-standards/btap/geometry.rb +486 -766
  35. data/lib/openstudio-standards/btap/linear_regression.rb +130 -0
  36. data/lib/openstudio-standards/btap/paths.rb +46 -0
  37. data/lib/openstudio-standards/btap/qaqc/analysis.rb +163 -0
  38. data/lib/openstudio-standards/btap/qaqc/data.rb +2293 -0
  39. data/lib/openstudio-standards/btap/qaqc/datapoint.rb +641 -0
  40. data/lib/openstudio-standards/btap/schedules.rb +11 -611
  41. data/lib/openstudio-standards/btap/structure.rb +574 -189
  42. data/lib/openstudio-standards/constructions/materials/information.rb +1 -1
  43. data/lib/openstudio-standards/create_typical/create_typical.rb +1 -1
  44. data/lib/openstudio-standards/exterior_lighting/create.rb +135 -85
  45. data/lib/openstudio-standards/exterior_lighting/data/typical_exterior_lighting.json +20 -0
  46. data/lib/openstudio-standards/exterior_lighting/information.rb +23 -2
  47. data/lib/openstudio-standards/geometry/create.rb +7 -3
  48. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +3 -2
  49. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +3 -2
  50. data/lib/openstudio-standards/prototypes/common/data/thermostat_schedule_lookup.json +84 -84
  51. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +4 -4
  52. data/lib/openstudio-standards/refrigeration/create_walkin.rb +45 -5
  53. data/lib/openstudio-standards/refrigeration/data/refrigerated_walkins.csv +75 -75
  54. data/lib/openstudio-standards/schedules/parametric.rb +6 -0
  55. data/lib/openstudio-standards/service_water_heating/create_typical.rb +10 -3
  56. data/lib/openstudio-standards/service_water_heating/create_water_heating_loop.rb +30 -14
  57. data/lib/openstudio-standards/service_water_heating/information.rb +4 -1
  58. data/lib/openstudio-standards/sql_file/unmet_hours.rb +2 -1
  59. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +3 -1
  60. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +3 -1
  61. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.boilers.json +12 -0
  62. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +18432 -3072
  63. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.boilers.json +26 -0
  64. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +8532 -1422
  65. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.boilers.json +26 -0
  66. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +8532 -1422
  67. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.boilers.json +16 -0
  68. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.computer_room_acs.json +30 -30
  69. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +7560 -1260
  70. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.PumpVariableSpeed.rb +1 -2
  71. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.boilers.json +16 -0
  72. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_properties.json +7560 -1260
  73. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +3 -3
  74. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.PumpVariableSpeed.rb +1 -2
  75. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.boilers.json +22 -0
  76. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_properties.json +7236 -1206
  77. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.furnaces.json +223 -19
  78. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.schedules.json +37 -1
  79. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.boilers.json +3 -0
  80. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_properties.json +6900 -1150
  81. data/lib/openstudio-standards/standards/cbes/data/cbes.schedules.json +1 -1
  82. data/lib/openstudio-standards/standards/deer/data/deer.schedules.json +1 -1
  83. data/lib/openstudio-standards/standards/necb/BTAP1980TO2010/data/surface_thermal_transmittance.json +76 -40
  84. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/surface_thermal_transmittance.json +76 -40
  85. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +6 -4
  86. data/lib/openstudio-standards/standards/necb/NECB2011/NECB2011_QAQC.json +2988 -0
  87. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +25 -3
  88. data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +672 -534
  89. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/Hospital.osm +1791 -1792
  90. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPMultiTower.osm +7 -1
  91. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPTownHouse.osm +7 -1
  92. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LargeHotel.osm +5 -6
  93. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LargeOffice.osm +8 -9
  94. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernEducation.osm +10 -4
  95. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernHealthCare.osm +14 -15
  96. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/Outpatient.osm +7 -1
  97. data/lib/openstudio-standards/standards/necb/NECB2011/data/surface_thermal_transmittance.json +76 -40
  98. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +14 -6
  99. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +542 -130
  100. data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +30 -63
  101. data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +7 -2
  102. data/lib/openstudio-standards/standards/necb/NECB2015/data/surface_thermal_transmittance.json +90 -0
  103. data/lib/openstudio-standards/standards/necb/NECB2015/necb_2015.rb +8 -6
  104. data/lib/openstudio-standards/standards/necb/NECB2017/data/surface_thermal_transmittance.json +76 -40
  105. data/lib/openstudio-standards/standards/necb/NECB2017/necb_2017.rb +2 -1
  106. data/lib/openstudio-standards/standards/necb/NECB2020/building_envelope.rb +0 -117
  107. data/lib/openstudio-standards/standards/necb/NECB2020/data/surface_thermal_transmittance.json +76 -45
  108. data/lib/openstudio-standards/standards/necb/NECB2020/necb_2020.rb +218 -0
  109. data/lib/openstudio-standards/standards/necb/common/construction_defaults.osm +12 -7
  110. data/lib/openstudio-standards/standards/standard.rb +1 -1
  111. data/lib/openstudio-standards/version.rb +1 -1
  112. data/lib/openstudio-standards.rb +9 -4
  113. metadata +59 -66
  114. data/data/inventory/thermal_bridging.csv +0 -90
  115. data/data/standards/OpenStudio_Standards-ashrae_90_1-ALL-comstock(space_types).xlsx +0 -0
  116. data/data/standards/openstudio_standards_duplicates_log.csv +0 -7962
  117. data/lib/openstudio-standards/btap/NECB_building_types.csv +0 -35
  118. data/lib/openstudio-standards/btap/NECB_space_types.csv +0 -109
  119. data/lib/openstudio-standards/btap/WeatherData1.json +0 -2110
  120. data/lib/openstudio-standards/btap/WeatherData1.xlsx +0 -0
  121. data/lib/openstudio-standards/btap/btap_result.rb +0 -1144
  122. data/lib/openstudio-standards/btap/btap_test_helper.rb +0 -86
  123. data/lib/openstudio-standards/btap/common_paths.rb +0 -81
  124. data/lib/openstudio-standards/btap/common_resources/ConstructionProperties.csv +0 -52
  125. data/lib/openstudio-standards/btap/common_resources/Constructions.csv +0 -37
  126. data/lib/openstudio-standards/btap/common_resources/construction_sets.csv +0 -1270
  127. data/lib/openstudio-standards/btap/common_resources/constructions_glazing.csv +0 -121
  128. data/lib/openstudio-standards/btap/common_resources/constructions_opaque.csv +0 -2256
  129. data/lib/openstudio-standards/btap/common_resources/costs.csv +0 -1897
  130. data/lib/openstudio-standards/btap/common_resources/costs_local_factors.csv +0 -2315
  131. data/lib/openstudio-standards/btap/common_resources/materials_glazing.csv +0 -35
  132. data/lib/openstudio-standards/btap/common_resources/materials_opaque.csv +0 -164
  133. data/lib/openstudio-standards/btap/costing/btap_measure_helper.rb +0 -359
  134. data/lib/openstudio-standards/btap/costing/btap_workflow.rb +0 -117
  135. data/lib/openstudio-standards/btap/costing/copy_test_results_files_to_expected_results.rb +0 -11
  136. data/lib/openstudio-standards/btap/costing/cost_building_from_file.rb +0 -136
  137. data/lib/openstudio-standards/btap/costing/costing_database_wrapper.rb +0 -173
  138. data/lib/openstudio-standards/btap/costing/dummy.epw +0 -8768
  139. data/lib/openstudio-standards/btap/costing/dummy.osm +0 -5320
  140. data/lib/openstudio-standards/btap/costing/neb_end_use_prices.csv +0 -42
  141. data/lib/openstudio-standards/btap/costing/necb_2011_spacetype_info.csv +0 -225
  142. data/lib/openstudio-standards/btap/costing/necb_reference_runs.csv +0 -28705
  143. data/lib/openstudio-standards/btap/costing/parallel_tests.rb +0 -92
  144. data/lib/openstudio-standards/btap/costing/test_list.txt +0 -15
  145. data/lib/openstudio-standards/btap/costing/test_run_all_test_locally.rb +0 -27
  146. data/lib/openstudio-standards/btap/costing/test_run_costing_tests.rb +0 -80
  147. data/lib/openstudio-standards/btap/necb_2011_spacetype_info.csv +0 -225
  148. data/lib/openstudio-standards/btap/utilities/Add_template_field_to_json.rb +0 -22
  149. data/lib/openstudio-standards/btap/utilities/convert_surfaces_to_adiabatic_necb_8426.rb +0 -204
  150. data/lib/openstudio-standards/btap/utilities/generate_space_types.rb +0 -8
  151. data/lib/openstudio-standards/btap/utilities/necb_to_epw_map.rb +0 -50
  152. data/lib/openstudio-standards/btap/utilities/os_sim_extract.rb +0 -48
  153. data/lib/openstudio-standards/btap/utilities/rename_surfaces.rb +0 -24
  154. data/lib/openstudio-standards/btap/utilities/round_surf_coords.rb +0 -32
  155. data/lib/openstudio-standards/btap/utilities/sched_create.rb +0 -145
  156. data/lib/openstudio-standards/btap/utilities/set_mult_to_adiabatic.rb +0 -53
  157. data/lib/openstudio-standards/btap/utilities/space_type.rb +0 -78
  158. data/lib/openstudio-standards/btap/utilities/weatherData1_xlsx_to_json.rb +0 -56
  159. data/lib/openstudio-standards/btap/vintagizer.rb +0 -161
  160. data/lib/openstudio-standards/btap/visualization.rb +0 -72
  161. data/lib/openstudio-standards/standards/necb/NECB2011/data/necb_2011_spacetype_info.csv +0 -225
  162. data/lib/openstudio-standards/standards/necb/common/btap_analysis.rb +0 -79
  163. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +0 -2656
  164. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +0 -653
  165. data/lib/openstudio-standards/standards/necb/common/necb_reference_runs.csv +0 -28705
  166. data/lib/openstudio-standards/standards/necb/common/utility_pricing_2025-02-20.csv +0 -92
  167. /data/lib/openstudio-standards/btap/{common_resources → common}/carbon_frame.csv +0 -0
  168. /data/lib/openstudio-standards/btap/{common_resources → common}/carbon_glazing.csv +0 -0
  169. /data/lib/openstudio-standards/btap/{common_resources → common}/carbon_opaque.csv +0 -0
  170. /data/lib/openstudio-standards/btap/{common_resources → common}/hvac_vent_ahu.csv +0 -0
  171. /data/lib/openstudio-standards/btap/{common_resources → common}/lighting.csv +0 -0
  172. /data/lib/openstudio-standards/btap/{common_resources → common}/lighting_sets.csv +0 -0
  173. /data/lib/openstudio-standards/btap/{common_resources → common}/locations.csv +0 -0
  174. /data/lib/openstudio-standards/btap/{costing → common}/mech_sizing.json +0 -0
@@ -0,0 +1,130 @@
1
+ module BTAP
2
+ module LinearRegression
3
+ @extrapolation_boundaries_exceeded = false
4
+
5
+ # Read and reset the error to not carry over from previous calls in the case
6
+ # of using this module across different facilities.
7
+ # @return [TrueClass|FalseClass]
8
+ def self.extrapolation_boundaries_exceeded?
9
+ value = @extrapolation_boundaries_exceeded
10
+ @extrapolation_boundaries_exceeded = false
11
+ return value
12
+ end
13
+
14
+ # @param message [String]
15
+ # @return [String]
16
+ def self.fmt(message)
17
+ return "#{[BTAP::LinearRegression]} #{message}"
18
+ end
19
+
20
+ # Interpolate a 2D array for the dependent variable `x2` and get the
21
+ # y-intercept. Sets the extrapolation class variable if extrapolation
22
+ # boundaries were exceeded.
23
+ # @param x_y_array [Array[Array]] 2D array of floats.
24
+ # @param x2 [Float] Dependent variable to be
25
+ # interpolated.
26
+ # @param extrapolation_range [Float]
27
+ # @return [[Float, String]] The interpolated y-intercept and the warning
28
+ # message, "OK" if none.
29
+ def self.interpolate(x_y_array:, x2:, extrapolation_range: 0.02)
30
+ notes = "OK"
31
+ array = x_y_array.uniq.sort { |a, b| a[0] <=> b[0] }
32
+ extrapolation_percent = extrapolation_range * 100
33
+
34
+ if array.empty?
35
+ return 0.0, fmt("Empty array given for interpolation, returning zero.")
36
+ elsif array.size == 1
37
+ return array.first[1].to_f, notes
38
+ end
39
+
40
+ x_lower_bound = (1.0 - extrapolation_range) * array[0][0]
41
+ x_upper_bound = (1.0 + extrapolation_range) * array[-1][0]
42
+ y_lower_bound = (1.0 - extrapolation_range) * array[0][1]
43
+ y_upper_bound = (1.0 + extrapolation_range) * array[-1][1]
44
+
45
+ if x2 < x_lower_bound
46
+ return y_lower_bound, fmt("Warning: Dependent variable #{x2} precedes the lower bound " \
47
+ "(#{x_lower_bound}) for the #{extrapolation_percent}% range. Returning the lower " \
48
+ "bound.")
49
+ elsif x2 > x_upper_bound
50
+ @extrapolation_boundaries_exceeded = true
51
+ return y_upper_bound, fmt("Warning: Dependent variable #{x2} exceeds the upper bound " \
52
+ "(#{x_upper_bound}) for the #{extrapolation_percent}% range. Returning the upper " \
53
+ "bound.")
54
+ elsif x2 < array.first[0].to_f
55
+
56
+ # Extrapolate down using first and second cost value to this
57
+ # out-of-range input.
58
+ x_array = [array[0][0].to_f, array[1][0].to_f]
59
+ y_array = [array[0][1].to_f, array[1][1].to_f]
60
+ linear_model = LinearModel.new(x_array, y_array)
61
+ y2 = linear_model.y_intercept + linear_model.slope * x2
62
+ return y2, notes
63
+ elsif x2 > array.last[0].to_f
64
+
65
+ # Extrapolate up using second to last and last cost value to this
66
+ # out-of-range input.
67
+ x_array = [array[-2][0].to_f, array[-1][0].to_f]
68
+ y_array = [array[-2][1].to_f, array[-1][1].to_f]
69
+ linear_model = LinearModel.new(x_array, y_array)
70
+ y2 = linear_model.y_intercept + linear_model.slope * x2
71
+ return y2, notes
72
+ else
73
+ array.each_index do |counter|
74
+
75
+ # skip last value.
76
+ next if array[counter] == array.last
77
+
78
+ x0 = array[counter][0]
79
+ y0 = array[counter][1]
80
+ x1 = array[counter + 1][0]
81
+ y1 = array[counter + 1][1]
82
+
83
+ # Skip if x2 is not between x0 and x1.
84
+ next if x2 < x0 || x2 > x1
85
+
86
+ y2 = y0 # Just in-case x0, x1 and x2 are identical.
87
+ if (x1 - x0) > 0.0
88
+ y2 = y0.to_f + ((y1 - y0).to_f * (x2 - x0).to_f / (x1 - x0).to_f)
89
+ end
90
+ return y2, notes
91
+ end
92
+ end
93
+ end
94
+
95
+ class LinearModel
96
+ def initialize(xs, ys)
97
+ @xs, @ys = xs, ys
98
+ if @xs.length != @ys.length
99
+ raise "Unbalanced data. xs need to be same length as ys"
100
+ end
101
+ end
102
+
103
+ def y_intercept
104
+ return mean(@ys) - (slope * mean(@xs))
105
+ end
106
+
107
+ def slope
108
+ x_mean = mean(@xs)
109
+ y_mean = mean(@ys)
110
+
111
+ numerator = (0...@xs.length).reduce(0) do |sum, i|
112
+ sum + ((@xs[i] - x_mean) * (@ys[i] - y_mean))
113
+ end
114
+
115
+ denominator = @xs.reduce(0) do |sum, x|
116
+ sum + ((x - x_mean) ** 2)
117
+ end
118
+
119
+ return (numerator / denominator)
120
+ end
121
+
122
+ def mean(values)
123
+ total = values.reduce(0) { |sum, x| x + sum }
124
+ return Float(total) / Float(values.length)
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+
@@ -0,0 +1,46 @@
1
+ # BTAP Paths
2
+ #
3
+ # File paths related to the common folder.
4
+
5
+ module BTAP
6
+ module Paths
7
+ class << self
8
+
9
+ # Costing paths are mutable in the `BTAP::Costing` constructor.
10
+ attr_accessor :costs_path
11
+ attr_accessor :costs_local_factors_path
12
+ end
13
+ btap_common = Pathname(__dir__) / "common"
14
+ necb_common = Pathname(__dir__) / "../standards/necb/common"
15
+ @costs_path = btap_common / "costs.csv"
16
+ @costs_local_factors_path = btap_common / "costs_local_factors.csv"
17
+
18
+ COSTING_DATA_PATHS = [
19
+ btap_common / "locations.csv",
20
+ btap_common / "materials_opaque.csv",
21
+ btap_common / "materials_glazing.csv",
22
+ btap_common / "lighting_sets.csv",
23
+ btap_common / "lighting.csv",
24
+ btap_common / "materials_lighting.csv",
25
+ btap_common / "hvac_vent_ahu.csv",
26
+ btap_common / "materials_hvac.csv"
27
+ ]
28
+
29
+ CONSTRUCTIONS_PATH = btap_common / "constructions.json"
30
+ CARBON_OPAQUE_PATH = btap_common / "carbon_opaque.csv"
31
+ CARBON_GLAZING_PATH = btap_common / "carbon_glazing.csv"
32
+ CARBON_FRAME_PATH = btap_common / "carbon_frame.csv"
33
+ THERMAL_BRIDGING_PATH = btap_common / "thermal_bridging.csv"
34
+ MECH_SIZING_PATH = btap_common / "mech_sizing.json"
35
+ NECB_BUILDING_TYPES_PATH = btap_common / "necb_building_types.csv"
36
+ NECB_SPACE_TYPES_PATH = btap_common / "necb_space_types.csv"
37
+
38
+ NEB_PRICES_PATH = necb_common / "neb_end_use_prices.csv"
39
+
40
+ # (Retrieved March 11, 2025)
41
+ # ECCC's emissions factors for the current and future years for GHG "without
42
+ # Biomass and RNG CO2 emissions":
43
+ # https://data-donnees.az.ec.gc.ca/data/substances/monitor/canada-s-greenhouse-gas-emissions-projections/Current-Projections-Actuelles/Energy-Energie/AM%20Scenario%20AMS/Grid-O%26G-Intensities-Intensites-Reseau-Delectricite-P%26G?lang=en
44
+ ECCC_GHG_ELECTRICITY_PATH = necb_common / "eccc_electric_grid_intensity_20250311.csv"
45
+ end
46
+ end
@@ -0,0 +1,163 @@
1
+ require 'openstudio'
2
+
3
+ module BTAP
4
+
5
+ # BTAP Analysis
6
+ #
7
+ # Class to instantiate post-analysis mechanisms like costing or carbon
8
+ # calculation. Can be done during a simulation or without one given an OSM file
9
+ # and its SQL file, along with a few other parameters.
10
+ #
11
+ # Abstract class, only instantiate BTAP::NoSimAnalysis or BTAP::DatapointAnalysis.
12
+ class Analysis
13
+ attr_accessor :attributes
14
+
15
+ # @param output_folder [String]
16
+ def initialize(output_folder:)
17
+ @output_folder = output_folder
18
+ end
19
+
20
+ # Run BTAP Costing.
21
+ #
22
+ # @param costs_csv [String] Path to a custom costing CSV file if custom
23
+ # costing is desired.
24
+ # @param factors_csv [String] Path to a custom costing localization factors
25
+ # CSV file if custom costing is desired.
26
+ def run_costing(costs_csv: Paths.costs_path, factors_csv: Paths.costs_local_factors_path)
27
+ costing = Costing.new(costs_csv: costs_csv, factors_csv: factors_csv, attributes: @attributes)
28
+
29
+ cost_result, _ = costing.cost_audit_all(
30
+ model: @model,
31
+ prototype_creator: @standard,
32
+ template_type: @model.getBuilding.standardsTemplate.get)
33
+
34
+ if not @qaqc.nil?
35
+ @qaqc[:costing_information] = cost_result
36
+ end
37
+
38
+ File.open(File.join(@output_folder, 'cost_results.json'), 'w') do |f|
39
+ f.write(JSON.pretty_generate(cost_result, allow_nan: true))
40
+ end
41
+ puts "Wrote File cost_results.json in #{@output_folder} "
42
+
43
+ return cost_result
44
+ end
45
+
46
+ # Run BTAP Carbon.
47
+ def run_carbon
48
+ carbon = Carbon.new(attributes: @attributes, standards_data: @standard.standards_data)
49
+ carbon_result = carbon.audit_embodied_carbon
50
+
51
+ if not @qaqc.nil?
52
+ @qaqc[:carbon_information] = carbon_result
53
+ end
54
+
55
+ File.open(File.join(@output_folder, 'carbon_results.json'), 'w') do |f|
56
+ f.write(JSON.pretty_generate(carbon_result, allow_nan: true))
57
+ end
58
+ puts "Wrote File carbon_results.json in #{@output_folder} "
59
+
60
+ return carbon_result
61
+ end
62
+
63
+ # @param model [OpenStudio::Model::Model]
64
+ # @return [(Boolean, Hash)]
65
+ def self.get_tbd_attributes(model:)
66
+
67
+ # The "psi_quality" additional property is only initialized when TBD
68
+ # is run, used as a marker here to determine the "tbd_enabled" attribute.
69
+ tbd_enabled = model.getBuilding.additionalProperties.hasFeature("psi_quality")
70
+ tbd_edge_tallies = {}
71
+
72
+ # Process the thermal bridging edge tallies out of the building's
73
+ # additional properties and format them into a hash.
74
+ if tbd_enabled
75
+ BTAP::BridgingData.admissible_edges.map(&:to_s).each do |edge_type|
76
+ (1..model.getDefaultConstructionSets.length).each do |id|
77
+ edge_key = "PSI#{edge_type}#{id}"
78
+ keep_looking = false
79
+ if model.getBuilding.additionalProperties.hasFeature(edge_key)
80
+ keep_looking = true
81
+ tbd_edge_tallies[edge_type] = {} unless tbd_edge_tallies.has_key?(edge_type)
82
+ wall_reference, quantity =
83
+ model.getBuilding.additionalProperties.getFeatureAsString(edge_key).get.split(/\s(?=\d)/)
84
+
85
+ tbd_edge_tallies[edge_type][wall_reference] = quantity.to_f
86
+ end
87
+ break unless keep_looking
88
+ end
89
+ end
90
+ end
91
+ return tbd_enabled, tbd_edge_tallies
92
+ end
93
+ end
94
+
95
+ # BTAP No Simulation Analysis
96
+ #
97
+ # Instantiate this class and run `run_costing` and/or `run_carbon` to run one
98
+ # of those modules without performing a full annual simulation or building a
99
+ # standard. This requires a number of parameters to be passed, all of which are
100
+ # provided from the simulation results of a full annual simulation. This
101
+ # requires some parameters of the Standard class to be manually loaded
102
+ # Therefore, a no-simulation analysis requires a full simulation to be run to
103
+ # retrieve the files necessary. Those files and other parameters are listed
104
+ # below:
105
+ #
106
+ # @param model_path [String] The path of the OSM file for a model.
107
+ # @param sql_file_path [String] SQL file of the model required for hourly
108
+ # data.
109
+ # @param output_folder [String]
110
+ # @param template [String]
111
+ # @param datapoint_id [String]
112
+ # @param analysis_id [String]
113
+ class NoSimAnalysis < Analysis
114
+ def initialize(
115
+ model_path:,
116
+ sql_file_path:,
117
+ output_folder:,
118
+ datapoint_id:,
119
+ analysis_id: SecureRandom.uuid)
120
+
121
+ super(output_folder: output_folder)
122
+ @model = BTAP::FileIO.load_osm(model_path)
123
+ @standard = Standard.build(@model.getBuilding.standardsTemplate.get)
124
+ @standard.assign_building_activity(model: @model)
125
+ @standard.assign_building_structure(model: @model, activity: @standard.activity)
126
+ @datapoint_id = datapoint_id
127
+ @analysis_id = analysis_id
128
+
129
+ tbd_enabled, tbd_edge_tallies = Analysis.get_tbd_attributes(model: @model)
130
+ @attributes = BTAP::Attributes.new(
131
+ model: @model,
132
+ standard: @standard,
133
+ tbd_enabled: tbd_enabled,
134
+ tbd_edge_tallies: tbd_edge_tallies)
135
+ @model.setSqlFile(OpenStudio::SqlFile.new(sql_file_path))
136
+ @qaqc = BTAP::Datapoint.build_qaqc(@model, @standard, @datapoint_id, @analysis_id)
137
+ end
138
+ end
139
+
140
+ # BTAP Datapoint Analysis
141
+ #
142
+ # Helper function to run post-analysis mechanisms in `btap_datapoint.rb`.
143
+ # @param model [OpenStudio::Model::Model]
144
+ # @param standard [Standard]
145
+ # @param template [String]
146
+ # @param qaqc [Hash] Doesn't seem to be currently relevant but still
147
+ # required.
148
+ class DatapointAnalysis < Analysis
149
+ def initialize(model:, output_folder:, standard:, qaqc:)
150
+ super(output_folder: output_folder)
151
+ @model = model
152
+ @standard = standard
153
+ @qaqc = qaqc
154
+
155
+ tbd_enabled, tbd_edge_tallies = Analysis.get_tbd_attributes(model: @model)
156
+ @attributes = BTAP::Attributes.new(
157
+ model: @model,
158
+ standard: @standard,
159
+ tbd_enabled: tbd_enabled,
160
+ tbd_edge_tallies: tbd_edge_tallies)
161
+ end
162
+ end
163
+ end