irie 0.0.16__py3-none-any.whl → 0.0.18__py3-none-any.whl

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.

Potentially problematic release.


This version of irie might be problematic. Click here for more details.

Files changed (35) hide show
  1. irie/apps/events/views_events.py +4 -6
  2. irie/apps/inventory/filters.py +37 -5
  3. irie/apps/inventory/models.py +14 -1
  4. irie/apps/inventory/sitemaps.py +19 -0
  5. irie/apps/inventory/views.py +2 -7
  6. irie/apps/prediction/forms.py +4 -1
  7. irie/apps/prediction/predictor.py +5 -274
  8. irie/apps/prediction/runners/__init__.py +17 -15
  9. irie/apps/prediction/runners/hazus.py +271 -182
  10. irie/apps/prediction/runners/opensees/__init__.py +88 -11
  11. irie/apps/prediction/runners/ssid.py +168 -9
  12. irie/apps/prediction/urls.py +3 -4
  13. irie/apps/prediction/views.py +8 -85
  14. irie/apps/sitemaps.py +14 -0
  15. irie/apps/static/assets/content_images/brace/mdof.svg +1 -0
  16. irie/apps/static/assets/content_images/brace/opensees.jpg +0 -0
  17. irie/apps/static/assets/content_images/brace/sdof.svg +327 -0
  18. irie/apps/static/assets/content_images/brace/sees.png +0 -0
  19. irie/apps/templates/accounts/login.html +50 -55
  20. irie/apps/templates/inventory/asset-profile.html +0 -15
  21. irie/apps/templates/inventory/asset-table.html +38 -15
  22. irie/apps/templates/prediction/asset-predictors.html +38 -5
  23. irie/apps/templates/prediction/new-runner.html +1 -1
  24. irie/apps/templates/prediction/predictor-profile.html +11 -0
  25. irie/apps/templates/site/index.html +5 -7
  26. irie/init/__main__.py +8 -5
  27. irie/init/data/cgs-stations.json +2967 -0
  28. irie/init/getCGSData.py +9 -4
  29. irie/init/management/commands/init_assets.py +1 -1
  30. irie/init/management/commands/init_cesmd.py +25 -0
  31. {irie-0.0.16.dist-info → irie-0.0.18.dist-info}/METADATA +1 -1
  32. {irie-0.0.16.dist-info → irie-0.0.18.dist-info}/RECORD +35 -27
  33. {irie-0.0.16.dist-info → irie-0.0.18.dist-info}/WHEEL +0 -0
  34. {irie-0.0.16.dist-info → irie-0.0.18.dist-info}/entry_points.txt +0 -0
  35. {irie-0.0.16.dist-info → irie-0.0.18.dist-info}/top_level.txt +0 -0
@@ -15,6 +15,8 @@ The seismic design of a bridge is taken into account in terms of the
15
15
  (iii) drift limits, and
16
16
  (iv) the longitudinal reinforcement ratio.
17
17
 
18
+ REFERENCES
19
+
18
20
  [1] Hazus earthquake technical manual
19
21
  https://www.fema.gov/sites/default/files/2020-10/fema_hazus_earthquake_technical_manual_4-2.pdf
20
22
 
@@ -24,148 +26,108 @@ The seismic design of a bridge is taken into account in terms of the
24
26
  [3] Mander and Basoz
25
27
  https://www.researchgate.net/profile/Jb-Mander/publication/292691534_Seismic_fragility_curve_theory_for_highway_bridges/links/5a7346d7aca2720bc0dbb653/Seismic-fragility-curve-theory-for-highway-bridges.pdf
26
28
 
27
- -------------------------------------------
28
-
29
- Table 9-6 in [2] (also 7-1 in [1])
30
-
31
- HWB1 All Non-CA < 1990 N/A > 150 N/A EQ1 0 Conventional Major Bridge - Length > 150 meters
32
- All CA < 1975 N/A > 150 N/A EQ1 0 Conventional Major Bridge - Length > 150 meters
33
- HWB2 All Non-CA >= 1990 N/A > 150 N/A EQ1 0 Seismic Major Bridge - Length > 150 meters
34
- All CA >= 1975 N/A > 150 N/A EQ1 0 Seismic Major Bridge - Length > 150 meters
35
- HWB3 All Non-CA < 1990 1 N/A N/A EQ1 1 Conventional Single Span
36
- All CA < 1975 1 N/A N/A EQ1 1 Conventional Single Span
37
- HWB4 All Non-CA >= 1990 1 N/A N/A EQ1 1 Seismic Single Span
38
- All CA >= 1975 1 N/A N/A EQ1 1 Seismic Single Span
39
- HWB5 101 106 Non-CA < 1990 N/A N/A N/A EQ1 0 Conventional Multi-Col. Bent, Simple Support - Concrete
40
- HWB6 101 106 CA < 1975 N/A N/A N/A EQ1 0 Conventional Multi-Col. Bent, Simple Support - Concrete
41
- HWB7 101 106 Non-CA >= 1990 N/A N/A N/A EQ1 0 Seismic Multi-Col. Bent, Simple Support - Concrete
42
- 101 106 CA >= 1975 N/A N/A N/A EQ1 0 Seismic Multi-Col. Bent, Simple Support - Concrete
43
- HWB8 205 206 CA < 1975 N/A N/A N/A EQ2 0 Conventional Single Col., Box Girder - Continuous Concrete
44
- HWB9 205 206 CA >= 1975 N/A N/A N/A EQ3 0 Seismic Single Col., Box Girder - Continuous Concrete
45
- HWB10 201 206 Non-CA < 1990 N/A N/A N/A EQ2 1 Conventional Continuous Concrete
46
- 201 206 CA < 1975 N/A N/A N/A EQ2 1 Conventional Continuous Concrete
47
- HWB11 201 206 Non-CA >= 1990 N/A N/A N/A EQ3 1 Seismic Continuous Concrete
48
- 201 206 CA >= 1975 N/A N/A N/A EQ3 1 Seismic Continuous Concrete
49
- HWB12 301 306 Non-CA < 1990 N/A N/A No EQ4 0 Conventional Multi-Col. Bent, Simple Support - Steel
50
- HWB13 301 306 CA < 1975 N/A N/A No EQ4 0 Conventional Multi-Col. Bent, Simple Support - Steel
51
- HWB14 301 306 Non-CA >= 1990 N/A N/A N/A EQ1 0 Seismic Multi-Col. Bent, Simple Support - Steel
52
- 301 306 CA >= 1975 N/A N/A N/A EQ1 0 Seismic Multi-Col. Bent, Simple Support - Steel
53
- HWB15 402 410 Non-CA < 1990 N/A N/A No EQ5 1 Conventional Continuous Steel
54
- 402 410 CA < 1975 N/A N/A No EQ5 1 Conventional Continuous Steel
55
- HWB16 402 410 Non-CA >= 1990 N/A N/A N/A EQ3 1 Seismic Continuous Steel
56
- 402 410 CA >= 1975 N/A N/A N/A EQ3 1 Seismic Continuous Steel
57
- HWB17 501 506 Non-CA < 1990 N/A N/A N/A EQ1 0 Conventional Multi-Col. Bent, Simple Support - Prestressed Concrete
58
- HWB18 501 506 CA < 1975 N/A N/A N/A EQ1 0 Conventional Multi-Col. Bent, Simple Support - Prestressed Concrete
59
- HWB19 501 506 Non-CA >= 1990 N/A N/A N/A EQ1 0 Seismic Multi-Col. Bent, Simple Support - Prestressed Concrete
60
- 501 506 CA >= 1975 N/A N/A N/A EQ1 0 Seismic Multi-Col. Bent, Simple Support - Prestressed Concrete
61
- HWB20 605 606 CA < 1975 N/A N/A N/A EQ2 0 Conventional Single Col., Box Girder - Prestressed Continuous Concrete
62
- HWB21 605 606 CA >= 1975 N/A N/A N/A EQ3 0 Seismic Single Col., Box Girder - Prestressed Continuous Concrete
63
- HWB22 601 607 Non-CA < 1990 N/A N/A N/A EQ2 1 Conventional Continuous Concrete
64
- 601 607 CA < 1975 N/A N/A N/A EQ2 1 Conventional Continuous Concrete
65
- HWB23 601 607 Non-CA >= 1990 N/A N/A N/A EQ3 1 Seismic Continuous Concrete
66
- 601 607 CA >= 1975 N/A N/A N/A EQ3 1 Seismic Continuous Concrete
67
- HWB24 301 306 Non-CA < 1990 N/A N/A Yes EQ6 0 Conventional Multi-Col. Bent, Simple Support - Steel
68
- HWB25 301 306 CA < 1975 N/A N/A Yes EQ6 0 Conventional Multi-Col. Bent, Simple Support - Steel
69
- HWB26 402 410 Non-CA < 1990 N/A N/A Yes EQ7 1 Conventional Continuous Steel
70
- HWB27 402 410 CA < 1975 N/A N/A Yes EQ7 1 Conventional Continuous Steel
71
- HWB28 N/A N/A All other bridges that are not classified
72
-
73
-
74
- --------------------------
75
-
76
- Table 9-7: Hazus Highway System Classification
77
-
78
- HWB1 Major Bridge - Length > 150 meters (Conventional Design)
79
- HWB2 Major Bridge - Length > 150 meters (Seismic Design)
80
- HWB3 Single Span - (Not HWB1 or HWB2) (Conventional Design)
81
- HWB4 Single Span - (Not HWB1 or HWB2) (Seismic Design)
82
- HWB5 Concrete, Multi-Column Bent, Simple Support (Conventional Design), Non-California (Non CA)
83
- HWB6 Concrete, Multi-Column Bent, Simple Support (Conventional Design), California (CA)
84
- HWB7 Concrete, Multi-Column Bent, Simple Support (Seismic Design)
85
- HWB8 Continuous Concrete, Single Column, Box Girder (Conventional Design)
86
- HWB9 Continuous Concrete, Single Column, Box Girder (Seismic Design)
87
- HWB10 Continuous Concrete, (Not HWB8 or HWB9) (Conventional Design)
88
- HWB11 Continuous Concrete, (Not HWB8 or HWB9) (Seismic Design)
89
- HWB12 Steel, Multi-Column Bent, Simple Support (Conventional Design), Non-California (Non-CA)
90
- HWB13 Steel, Multi-Column Bent, Simple Support (Conventional Design), California (CA)
91
- HWB14 Steel, Multi-Column Bent, Simple Support (Seismic Design)
92
- HWB15 Continuous Steel (Conventional Design)
93
- HWB16 Continuous Steel (Seismic Design)
94
- HWB17 PS Concrete Multi-Column Bent, Simple Support (Conventional Design), Non-California
95
- HWB18 PS Concrete, Multi-Column Bent, Simple Support (Conventional Design), California (CA)
96
- HWB19 PS Concrete, Multi-Column Bent, Simple Support (Seismic Design)
97
- HWB20 PS Concrete, Single Column, Box Girder (Conventional Design)
98
- HWB21 PS Concrete, Single Column, Box Girder (Seismic Design)
99
- HWB22 Continuous Concrete, (Not HWB20/HWB21) (Conventional Design)
100
- HWB23 Continuous Concrete, (Not HWB20/HWB21) (Seismic Design)
101
- HWB24 Same definition as HWB12 except the bridge length is less than 20 meters
102
- HWB25 Same definition as HWB13 except the bridge length is less than 20 meters
103
- HWB26 Same definition as HWB15 except the bridge length is less than 20 meters and Non-CA
104
- HWB27 Same definition as HWB15 except the bridge length is less than 20 meters and in CA
105
- HWB28 All other bridges that are not classified (including wooden bridges)
106
-
107
-
108
- -----------------------------
109
-
110
- Table 7-6 Fragility Function Median Values for Highway Bridges
111
-
112
- HWB1 0.40 0.50 0.70 0.90 3.9 3.9 3.9 13.8
113
- HWB2 0.60 0.90 1.10 1.70 3.9 3.9 3.9 13.8
114
- HWB3 0.80 1.00 1.20 1.70 3.9 3.9 3.9 13.8
115
- HWB4 0.80 1.00 1.20 1.70 3.9 3.9 3.9 13.8
116
- HWB5 0.25 0.35 0.45 0.70 3.9 3.9 3.9 13.8
117
- HWB6 0.30 0.50 0.60 0.90 3.9 3.9 3.9 13.8
118
- HWB7 0.50 0.80 1.10 1.70 3.9 3.9 3.9 13.8
119
- HWB8 0.35 0.45 0.55 0.80 3.9 3.9 3.9 13.8
120
- HWB9 0.60 0.90 1.30 1.60 3.9 3.9 3.9 13.8
121
- HWB10 0.60 0.90 1.10 1.50 3.9 3.9 3.9 13.8
122
- HWB11 0.90 0.90 1.10 1.50 3.9 3.9 3.9 13.8
123
- HWB12 0.25 0.35 0.45 0.70 3.9 3.9 3.9 13.8
124
- HWB13 0.30 0.50 0.60 0.90 3.9 3.9 3.9 13.8
125
- HWB14 0.50 0.80 1.10 1.70 3.9 3.9 3.9 13.8
126
- HWB15 0.75 0.75 0.75 1.10 3.9 3.9 3.9 13.8
127
- HWB16 0.90 0.90 1.10 1.50 3.9 3.9 3.9 13.8
128
- HWB17 0.25 0.35 0.45 0.70 3.9 3.9 3.9 13.8
129
- HWB18 0.30 0.50 0.60 0.90 3.9 3.9 3.9 13.8
130
- HWB19 0.50 0.80 1.10 1.70 3.9 3.9 3.9 13.8
131
- HWB20 0.35 0.45 0.55 0.80 3.9 3.9 3.9 13.8
132
- HWB21 0.60 0.90 1.30 1.60 3.9 3.9 3.9 13.8
133
- HWB22 0.60 0.90 1.10 1.50 3.9 3.9 3.9 13.8
134
- HWB23 0.90 0.90 1.10 1.50 3.9 3.9 3.9 13.8
135
- HWB24 0.25 0.35 0.45 0.70 3.9 3.9 3.9 13.8
136
- HWB25 0.30 0.50 0.60 0.90 3.9 3.9 3.9 13.8
137
- HWB26 0.75 0.75 0.75 1.10 3.9 3.9 3.9 13.8
138
- HWB27 0.75 0.75 0.75 1.10 3.9 3.9 3.9 13.8
139
- HWB28 0.80 1.00 1.20 1.70 3.9 3.9 3.9 13.8
29
+
140
30
  """
141
31
  import math
32
+ import json
142
33
  from scipy.stats import norm
34
+ from irie.apps.events.models import EventRecord
35
+ from irie.apps.prediction.runners import Runner, RunID
36
+ from irie.apps.prediction.models import PredictorModel
143
37
 
144
38
  Slight, Moderate, Extensive, Complete = range(4)
39
+ LEVELS = ["Slight", "Moderate", "Extensive", "Complete"]
145
40
 
146
41
  # State codes; We'll add more later, right now we assume
147
42
  # everything is in California
148
43
  class StateCodes:
149
44
  California = 22
150
45
 
46
+ class HazusRunner(Runner):
47
+ platform = "mdof"
48
+
49
+ schema = {
50
+ "title": "System ID",
51
+ "name": "P2",
52
+ "type": "object",
53
+ "required": [
54
+ "name",
55
+ "decimation",
56
+ "method",
57
+ "channels"
58
+ ],
59
+ "properties": {
60
+ "name": {
61
+ "type": "string",
62
+ "title": "Name",
63
+ "description": "Predictor name",
64
+ "minLength": 2,
65
+ # "default": "S1"
66
+ },
67
+ "method": {
68
+ "type": "string",
69
+ "title": "Method",
70
+ "enum": ["Fourier Spectrum","Response Spectrum","SRIM","OKID"]
71
+ },
72
+ "damping": {
73
+ "type": "number",
74
+ "title": "Damping",
75
+ "default": 0.02,
76
+ "options": {"dependencies": {"method": ["Response Spectrum"]}},
77
+ "description": "assumed damping ratio"
78
+ },
79
+ "channel": {
80
+ "type": "integer",
81
+ "title": "Channel",
82
+ "description": ""
83
+ }
84
+ }
85
+ }
86
+
87
+ def render(self):
88
+ return
89
+
90
+ @classmethod
91
+ def create(cls, asset, request):
92
+ predictor = PredictorModel()
93
+ data = json.loads(request.body)
94
+
95
+ data["metrics"] = [""]
96
+
97
+ predictor.name = data.pop("name")
98
+ predictor.config = data
99
+ predictor.asset = asset
100
+ predictor.protocol = "IRIE_PREDICTOR_T3"
101
+ predictor.active = True
102
+ return predictor
103
+
104
+ def newPrediction(self, event):
105
+ self.event = event
106
+ return RunID(1)
107
+
108
+ def runPrediction(self, run_id: RunID) -> bool:
109
+ try:
110
+ self.metric_data = ...
111
+ return True
112
+ except Exception as e:
113
+ self.metric_data = {"error": str(e)}
114
+ return False
115
+
116
+ def getMetricData(self, run, metric):
117
+ if not hasattr(self, "metric_data"):
118
+ raise Exception(f"Error {self.name}({id(self)}), {run}")
119
+ return self.metric_data
120
+
121
+
151
122
  def hazus_fragility(
152
- nbi_data: dict,
153
- pga: float = 0.5, # Peak Ground Acceleration (g)
154
- sa_03s: float = 1.1, # Spectral Acceleration at 0.3 seconds (g)
155
- sa_10s: float = 1.4, # Spectral Acceleration at 1.0 seconds (g)
156
- soil_type: str = "B", # Soil classification ("A", "B", "C", "D", "E")
157
- level: int = None, # Optional: Specify a damage state (0 = Slight, 1 = Moderate, etc.)
158
- generate_plot: bool = False, # Generate fragility curve plot
159
- return_data: bool = False
160
- ) -> dict:
123
+ nbi_data: dict,
124
+ soil_type: str = "B", # Soil classification ("A", "B", "C", "D", "E")
125
+ ) -> dict:
161
126
  """
162
127
  Compute fragility probabilities for a given bridge using the Hazus methodology.
163
128
 
164
129
  Args:
165
130
  - nbi_data (dict): NBI data containing bridge-specific properties.
166
- - pga (float): Peak Ground Acceleration (g).
167
- - sa_03s (float): Spectral Acceleration at 0.3 seconds (g).
168
- - sa_10s (float): Spectral Acceleration at 1.0 seconds (g).
169
131
  - soil_type (str): Soil classification ("A", "B", "C", "D", "E").
170
132
  - level (int): Specify a damage state (0 = Slight, 1 = Moderate, etc.) (optional).
171
133
  - generate_plot (bool): Whether to generate and return fragility curve plots.
@@ -177,43 +139,53 @@ def hazus_fragility(
177
139
  # Step 0: Extract relevant bridge properties
178
140
  properties = _bridge_info(nbi_data)
179
141
 
142
+ # Step 1: Determine Hazus bridge type
143
+ hazus_type: int = _hazus_type(properties)
144
+ if hazus_type == -1:
145
+ raise ValueError("Bridge type not found in Hazus classification")
146
+
147
+ # Step 3: Generate fragility curve
148
+
149
+ # Adjust sa_range to start from 0
150
+ sa_range = [0.0] + [0.1 * i for i in range(1, 21)] # Include 0 explicitly
151
+
152
+ curves = {state: [] for state in LEVELS}
153
+
154
+ # Generate fragility values, handling the case for Sa = 0
155
+ for sa in sa_range:
156
+ for state in LEVELS:
157
+ median = _get_old_medians(hazus_type)[state]
158
+ dispersion = 0.6 # β (dispersion factor)
159
+ curves[state].append(
160
+ norm.cdf((math.log(sa / median)) / dispersion) if sa > 0 else 0
161
+ )
162
+
163
+ return dict(sa_range=sa_range, curves=curves)
164
+
165
+ def hazus_prediction(
166
+ nbi_data: dict,
167
+ soil_type: str = "B", # Soil classification ("A", "B", "C", "D", "E")
168
+ sa_03s: float = 1.1, # Spectral Acceleration at 0.3 seconds (g)
169
+ sa_10s: float = 1.4, # Spectral Acceleration at 1.0 seconds (g)
170
+ level: int = None, # Optional: Specify a damage state (0 = Slight, 1 = Moderate, etc.)
171
+ ):
172
+ # Step 0: Extract relevant bridge properties
173
+ properties = _bridge_info(nbi_data)
174
+
180
175
  # Step 1: Determine Hazus bridge type
181
176
  hazus_type: int = _hazus_type(properties)
182
177
  if hazus_type == -1:
183
178
  raise ValueError("Bridge type not found in Hazus classification")
184
179
 
185
180
  # Step 2: Call _hazus_curve to compute fragility probabilities
186
- fragility_probs = _hazus_curve(hazus_type, properties, pga, sa_03s, sa_10s, soil_type)
187
-
188
- # Step 3: Generate fragility curve plot if requested
189
- if generate_plot or return_data:
190
- # Adjust sa_range to start from 0
191
- sa_range = [0.0] + [0.1 * i for i in range(1, 21)] # Include 0 explicitly
192
-
193
- curves = {state: [] for state in fragility_probs.keys()}
194
-
195
- # Generate fragility values, handling the case for Sa = 0
196
- for sa in sa_range:
197
- for state in fragility_probs.keys():
198
- median = get_old_medians(hazus_type)[state]
199
- dispersion = 0.6 # β (dispersion factor)
200
- curves[state].append(
201
- norm.cdf((math.log(sa / median)) / dispersion) if sa > 0 else 0
202
- )
203
-
204
- if return_data:
205
- fragility_probs["curves"] = curves
206
- fragility_probs["sa_range"] = sa_range
181
+ fragility_probs = _hazus_curve(hazus_type, properties, sa_03s, sa_10s, soil_type)
207
182
 
208
183
  # Step 4: Handle `level` as an integer
209
- damage_states = ["Slight", "Moderate", "Extensive", "Complete"]
210
184
  if level is not None:
211
185
  if level not in range(4):
212
186
  raise ValueError(f"Invalid level: {level}. Must be an integer in range(4).")
213
- damage_state = damage_states[level]
214
- return fragility_probs[damage_state]
187
+ return fragility_probs[LEVELS.index(level)]
215
188
 
216
- # Step 5: Return all probabilities and optionally the plot
217
189
  return fragility_probs
218
190
 
219
191
 
@@ -254,10 +226,11 @@ def _bridge_info(nbi: dict) -> dict:
254
226
 
255
227
 
256
228
 
257
- def _hazus_curve(type: int, properties: dict, pga: float, sa_03s: float, sa_10s: float, soil_type: str) -> dict:
229
+ def _hazus_curve(type: int, properties: dict, sa_03s: float, sa_10s: float, soil_type: str) -> dict:
258
230
  """
259
231
  Compute fragility probabilities for the four damage states and optionally generate fragility curves.
260
232
 
233
+ See page 7-14 of [1]
261
234
  Args:
262
235
  - type (int): Bridge classification (integer from 1 to 28).
263
236
  - properties (dict): Dictionary containing bridge-specific properties.
@@ -265,7 +238,6 @@ def _hazus_curve(type: int, properties: dict, pga: float, sa_03s: float, sa_10s:
265
238
  - sa_03s (float): Spectral Acceleration at 0.3 seconds (g).
266
239
  - sa_10s (float): Spectral Acceleration at 1.0 seconds (g).
267
240
  - soil_type (str): Soil classification ("A", "B", "C", "D", "E").
268
- - generate_curve (bool): If True, generate and display fragility curves.
269
241
 
270
242
  Returns:
271
243
  - dict: Fragility probabilities for Slight, Moderate, Extensive, and Complete damage states.
@@ -283,31 +255,32 @@ def _hazus_curve(type: int, properties: dict, pga: float, sa_03s: float, sa_10s:
283
255
  span_count = properties["span_count"]
284
256
  skew_angle = properties["skew_angle"]
285
257
 
286
- # Call modify_ground_motion to get the modified values
287
- modified_values = modify_ground_motion(pga, sa_03s, sa_10s, soil_type)
288
- modified_pga = modified_values['modified_pga']
289
- modified_sa_03s = modified_values['modified_sa_03s']
290
- modified_sa_10s = modified_values['modified_sa_10s']
258
+ # Step 2: Get soil-amplified shaking parameters
259
+ modified_values = modify_ground_motion(soil_type, None, sa_03s, sa_10s)
260
+ modified_sa_03s = modified_values['sa_03s']
261
+ modified_sa_10s = modified_values['sa_10s']
291
262
 
263
+ # Step 3: Compute modification factors
292
264
  # Compute K_skew, K_shape, K3D
293
265
  K_skew = math.sqrt(math.sin(math.radians(90 - skew_angle)))
294
266
  if modified_sa_03s == 0:
295
267
  raise ValueError("Modified Sa(0.3 sec) cannot be zero.")
268
+
296
269
  K_shape = (2.5 * modified_sa_10s) / modified_sa_03s
297
- A, B = get_a_b(type)
270
+ A, B = _get_a_b(type)
298
271
  if span_count - B == 0:
299
272
  raise ValueError("Invalid span count resulting in division by zero.")
300
273
  K3D = 1 + A / (span_count - B)
301
274
 
275
+ # Step 4: Modify shaking medians
302
276
  # Retrieve old medians and compute new medians
303
- old_medians = get_old_medians(type)
304
- I_shape = get_i_shape(type)
277
+ old_medians = _get_old_medians(type)
278
+ I_shape = _get_i_shape(type)
305
279
  factor_slight = 1 if I_shape == 0 else min(1, K_shape)
306
280
 
307
281
  new_medians = {"Slight": old_medians["Slight"] * factor_slight}
308
- damage_states = ["Moderate", "Extensive", "Complete"]
309
282
  new_medians.update(
310
- {state: old_medians[state] * K_skew * K3D for state in damage_states}
283
+ {state: old_medians[state] * K_skew * K3D for state in ["Moderate", "Extensive", "Complete"]}
311
284
  )
312
285
 
313
286
  # Compute fragility probabilities
@@ -316,6 +289,7 @@ def _hazus_curve(type: int, properties: dict, pga: float, sa_03s: float, sa_10s:
316
289
 
317
290
  if modified_sa_10s <= 0:
318
291
  raise ValueError("Modified Sa(1.0 sec) must be positive.")
292
+
319
293
  fragility_probs = {
320
294
  state: compute_probability(modified_sa_10s, median)
321
295
  for state, median in new_medians.items()
@@ -324,7 +298,7 @@ def _hazus_curve(type: int, properties: dict, pga: float, sa_03s: float, sa_10s:
324
298
  return fragility_probs
325
299
 
326
300
 
327
- def modify_ground_motion(pga: float, sa_03s: float, sa_10s: float, soil_type: str) -> dict:
301
+ def modify_ground_motion(soil_type: str, pga: float, sa_03s: float, sa_10s: float) -> dict:
328
302
  """
329
303
  Modify PGA, Sa(0.3 sec), and Sa(1.0 sec) based on soil amplification factors (Table 4.7).
330
304
 
@@ -386,16 +360,18 @@ def modify_ground_motion(pga: float, sa_03s: float, sa_10s: float, soil_type: st
386
360
  raise ValueError("Interpolation failed unexpectedly.")
387
361
 
388
362
  # Calculate modified values
389
- modified_pga = pga * get_factor(pga, "FPGA")
390
- modified_sa_03s = sa_03s * get_factor(sa_03s, "FA")
391
- modified_sa_10s = sa_10s * get_factor(sa_10s, "FV")
363
+ outputs = {}
364
+ if pga is not None:
365
+ outputs["pga"] = pga * get_factor(pga, "FPGA")
366
+ if sa_03s is not None:
367
+ outputs["sa_03s"] = sa_03s * get_factor(sa_03s, "FA")
368
+ if sa_10s is not None:
369
+ outputs["sa_10s"] = sa_10s * get_factor(sa_10s, "FV")
392
370
 
393
- return {"modified_pga": modified_pga,
394
- "modified_sa_03s": modified_sa_03s,
395
- "modified_sa_10s": modified_sa_10s,
396
- }
371
+ return outputs
397
372
 
398
- def get_a_b(bridge_type: int) -> tuple:
373
+
374
+ def _get_a_b(bridge_type: int) -> tuple:
399
375
  """
400
376
  Retrieve coefficients A and B for K3D calculation based on bridge type.
401
377
 
@@ -431,7 +407,7 @@ def get_a_b(bridge_type: int) -> tuple:
431
407
  # Retrieve and return A and B values
432
408
  return equation_to_ab[equation]
433
409
 
434
- def get_i_shape(bridge_type: int) -> int:
410
+ def _get_i_shape(bridge_type: int) -> int:
435
411
  """
436
412
  Retrieve I_shape (indicator for skew effects) for the given bridge type
437
413
  from Table 7-1.
@@ -456,7 +432,7 @@ def get_i_shape(bridge_type: int) -> int:
456
432
 
457
433
  return i_shape_mapping[bridge_type]
458
434
 
459
- def get_old_medians(bridge_type: int) -> dict:
435
+ def _get_old_medians(bridge_type: int) -> dict:
460
436
  """
461
437
  Retrieve the old medians for Slight, Moderate, Extensive, and Complete damage states
462
438
  from Table 7-6 based on the bridge type.
@@ -466,17 +442,50 @@ def get_old_medians(bridge_type: int) -> dict:
466
442
 
467
443
  Returns:
468
444
  - dict: Old median values for each damage state.
445
+
446
+
447
+ Table 7-6 Fragility Function Median Values for Highway Bridges
448
+
449
+ HWB1 0.40 0.50 0.70 0.90 3.9 3.9 3.9 13.8
450
+ HWB2 0.60 0.90 1.10 1.70 3.9 3.9 3.9 13.8
451
+ HWB3 0.80 1.00 1.20 1.70 3.9 3.9 3.9 13.8
452
+ HWB4 0.80 1.00 1.20 1.70 3.9 3.9 3.9 13.8
453
+ HWB5 0.25 0.35 0.45 0.70 3.9 3.9 3.9 13.8
454
+ HWB6 0.30 0.50 0.60 0.90 3.9 3.9 3.9 13.8
455
+ HWB7 0.50 0.80 1.10 1.70 3.9 3.9 3.9 13.8
456
+ HWB8 0.35 0.45 0.55 0.80 3.9 3.9 3.9 13.8
457
+ HWB9 0.60 0.90 1.30 1.60 3.9 3.9 3.9 13.8
458
+ HWB10 0.60 0.90 1.10 1.50 3.9 3.9 3.9 13.8
459
+ HWB11 0.90 0.90 1.10 1.50 3.9 3.9 3.9 13.8
460
+ HWB12 0.25 0.35 0.45 0.70 3.9 3.9 3.9 13.8
461
+ HWB13 0.30 0.50 0.60 0.90 3.9 3.9 3.9 13.8
462
+ HWB14 0.50 0.80 1.10 1.70 3.9 3.9 3.9 13.8
463
+ HWB15 0.75 0.75 0.75 1.10 3.9 3.9 3.9 13.8
464
+ HWB16 0.90 0.90 1.10 1.50 3.9 3.9 3.9 13.8
465
+ HWB17 0.25 0.35 0.45 0.70 3.9 3.9 3.9 13.8
466
+ HWB18 0.30 0.50 0.60 0.90 3.9 3.9 3.9 13.8
467
+ HWB19 0.50 0.80 1.10 1.70 3.9 3.9 3.9 13.8
468
+ HWB20 0.35 0.45 0.55 0.80 3.9 3.9 3.9 13.8
469
+ HWB21 0.60 0.90 1.30 1.60 3.9 3.9 3.9 13.8
470
+ HWB22 0.60 0.90 1.10 1.50 3.9 3.9 3.9 13.8
471
+ HWB23 0.90 0.90 1.10 1.50 3.9 3.9 3.9 13.8
472
+ HWB24 0.25 0.35 0.45 0.70 3.9 3.9 3.9 13.8
473
+ HWB25 0.30 0.50 0.60 0.90 3.9 3.9 3.9 13.8
474
+ HWB26 0.75 0.75 0.75 1.10 3.9 3.9 3.9 13.8
475
+ HWB27 0.75 0.75 0.75 1.10 3.9 3.9 3.9 13.8
476
+ HWB28 0.80 1.00 1.20 1.70 3.9 3.9 3.9 13.8
469
477
  """
478
+
470
479
  old_medians = {
471
- 1: {"Slight": 0.40, "Moderate": 0.50, "Extensive": 0.70, "Complete": 0.90},
472
- 2: {"Slight": 0.60, "Moderate": 0.90, "Extensive": 1.10, "Complete": 1.70},
473
- 3: {"Slight": 0.80, "Moderate": 1.00, "Extensive": 1.20, "Complete": 1.70},
474
- 4: {"Slight": 0.80, "Moderate": 1.00, "Extensive": 1.20, "Complete": 1.70},
475
- 5: {"Slight": 0.25, "Moderate": 0.35, "Extensive": 0.45, "Complete": 0.70},
476
- 6: {"Slight": 0.30, "Moderate": 0.50, "Extensive": 0.60, "Complete": 0.90},
477
- 7: {"Slight": 0.50, "Moderate": 0.80, "Extensive": 1.10, "Complete": 1.70},
478
- 8: {"Slight": 0.35, "Moderate": 0.45, "Extensive": 0.55, "Complete": 0.80},
479
- 9: {"Slight": 0.60, "Moderate": 0.90, "Extensive": 1.30, "Complete": 1.60},
480
+ 1: {"Slight": 0.40, "Moderate": 0.50, "Extensive": 0.70, "Complete": 0.90},
481
+ 2: {"Slight": 0.60, "Moderate": 0.90, "Extensive": 1.10, "Complete": 1.70},
482
+ 3: {"Slight": 0.80, "Moderate": 1.00, "Extensive": 1.20, "Complete": 1.70},
483
+ 4: {"Slight": 0.80, "Moderate": 1.00, "Extensive": 1.20, "Complete": 1.70},
484
+ 5: {"Slight": 0.25, "Moderate": 0.35, "Extensive": 0.45, "Complete": 0.70},
485
+ 6: {"Slight": 0.30, "Moderate": 0.50, "Extensive": 0.60, "Complete": 0.90},
486
+ 7: {"Slight": 0.50, "Moderate": 0.80, "Extensive": 1.10, "Complete": 1.70},
487
+ 8: {"Slight": 0.35, "Moderate": 0.45, "Extensive": 0.55, "Complete": 0.80},
488
+ 9: {"Slight": 0.60, "Moderate": 0.90, "Extensive": 1.30, "Complete": 1.60},
480
489
  10: {"Slight": 0.60, "Moderate": 0.90, "Extensive": 1.10, "Complete": 1.50},
481
490
  11: {"Slight": 0.90, "Moderate": 0.90, "Extensive": 1.10, "Complete": 1.50},
482
491
  12: {"Slight": 0.25, "Moderate": 0.35, "Extensive": 0.45, "Complete": 0.70},
@@ -513,6 +522,86 @@ def _hazus_type(properties: dict) -> int:
513
522
 
514
523
  Returns:
515
524
  int: Hazus type classification (1-28) or -1 if no match is found
525
+
526
+
527
+ Table 9-6 in [2] (also 7-1 in [1])
528
+
529
+ HWB1 All Non-CA < 1990 N/A > 150 N/A EQ1 0 Conventional Major Bridge - Length > 150 meters
530
+ All CA < 1975 N/A > 150 N/A EQ1 0 Conventional Major Bridge - Length > 150 meters
531
+ HWB2 All Non-CA >= 1990 N/A > 150 N/A EQ1 0 Seismic Major Bridge - Length > 150 meters
532
+ All CA >= 1975 N/A > 150 N/A EQ1 0 Seismic Major Bridge - Length > 150 meters
533
+ HWB3 All Non-CA < 1990 1 N/A N/A EQ1 1 Conventional Single Span
534
+ All CA < 1975 1 N/A N/A EQ1 1 Conventional Single Span
535
+ HWB4 All Non-CA >= 1990 1 N/A N/A EQ1 1 Seismic Single Span
536
+ All CA >= 1975 1 N/A N/A EQ1 1 Seismic Single Span
537
+ HWB5 101 106 Non-CA < 1990 N/A N/A N/A EQ1 0 Conventional Multi-Col. Bent, Simple Support - Concrete
538
+ HWB6 101 106 CA < 1975 N/A N/A N/A EQ1 0 Conventional Multi-Col. Bent, Simple Support - Concrete
539
+ HWB7 101 106 Non-CA >= 1990 N/A N/A N/A EQ1 0 Seismic Multi-Col. Bent, Simple Support - Concrete
540
+ 101 106 CA >= 1975 N/A N/A N/A EQ1 0 Seismic Multi-Col. Bent, Simple Support - Concrete
541
+ HWB8 205 206 CA < 1975 N/A N/A N/A EQ2 0 Conventional Single Col., Box Girder - Continuous Concrete
542
+ HWB9 205 206 CA >= 1975 N/A N/A N/A EQ3 0 Seismic Single Col., Box Girder - Continuous Concrete
543
+ HWB10 201 206 Non-CA < 1990 N/A N/A N/A EQ2 1 Conventional Continuous Concrete
544
+ 201 206 CA < 1975 N/A N/A N/A EQ2 1 Conventional Continuous Concrete
545
+ HWB11 201 206 Non-CA >= 1990 N/A N/A N/A EQ3 1 Seismic Continuous Concrete
546
+ 201 206 CA >= 1975 N/A N/A N/A EQ3 1 Seismic Continuous Concrete
547
+ HWB12 301 306 Non-CA < 1990 N/A N/A No EQ4 0 Conventional Multi-Col. Bent, Simple Support - Steel
548
+ HWB13 301 306 CA < 1975 N/A N/A No EQ4 0 Conventional Multi-Col. Bent, Simple Support - Steel
549
+ HWB14 301 306 Non-CA >= 1990 N/A N/A N/A EQ1 0 Seismic Multi-Col. Bent, Simple Support - Steel
550
+ 301 306 CA >= 1975 N/A N/A N/A EQ1 0 Seismic Multi-Col. Bent, Simple Support - Steel
551
+ HWB15 402 410 Non-CA < 1990 N/A N/A No EQ5 1 Conventional Continuous Steel
552
+ 402 410 CA < 1975 N/A N/A No EQ5 1 Conventional Continuous Steel
553
+ HWB16 402 410 Non-CA >= 1990 N/A N/A N/A EQ3 1 Seismic Continuous Steel
554
+ 402 410 CA >= 1975 N/A N/A N/A EQ3 1 Seismic Continuous Steel
555
+ HWB17 501 506 Non-CA < 1990 N/A N/A N/A EQ1 0 Conventional Multi-Col. Bent, Simple Support - Prestressed Concrete
556
+ HWB18 501 506 CA < 1975 N/A N/A N/A EQ1 0 Conventional Multi-Col. Bent, Simple Support - Prestressed Concrete
557
+ HWB19 501 506 Non-CA >= 1990 N/A N/A N/A EQ1 0 Seismic Multi-Col. Bent, Simple Support - Prestressed Concrete
558
+ 501 506 CA >= 1975 N/A N/A N/A EQ1 0 Seismic Multi-Col. Bent, Simple Support - Prestressed Concrete
559
+ HWB20 605 606 CA < 1975 N/A N/A N/A EQ2 0 Conventional Single Col., Box Girder - Prestressed Continuous Concrete
560
+ HWB21 605 606 CA >= 1975 N/A N/A N/A EQ3 0 Seismic Single Col., Box Girder - Prestressed Continuous Concrete
561
+ HWB22 601 607 Non-CA < 1990 N/A N/A N/A EQ2 1 Conventional Continuous Concrete
562
+ 601 607 CA < 1975 N/A N/A N/A EQ2 1 Conventional Continuous Concrete
563
+ HWB23 601 607 Non-CA >= 1990 N/A N/A N/A EQ3 1 Seismic Continuous Concrete
564
+ 601 607 CA >= 1975 N/A N/A N/A EQ3 1 Seismic Continuous Concrete
565
+ HWB24 301 306 Non-CA < 1990 N/A N/A Yes EQ6 0 Conventional Multi-Col. Bent, Simple Support - Steel
566
+ HWB25 301 306 CA < 1975 N/A N/A Yes EQ6 0 Conventional Multi-Col. Bent, Simple Support - Steel
567
+ HWB26 402 410 Non-CA < 1990 N/A N/A Yes EQ7 1 Conventional Continuous Steel
568
+ HWB27 402 410 CA < 1975 N/A N/A Yes EQ7 1 Conventional Continuous Steel
569
+ HWB28 N/A N/A All other bridges that are not classified
570
+
571
+
572
+ --------------------------
573
+
574
+ Table 9-7: Hazus Highway System Classification
575
+
576
+ HWB1 Major Bridge - Length > 150 meters (Conventional Design)
577
+ HWB2 Major Bridge - Length > 150 meters (Seismic Design)
578
+ HWB3 Single Span - (Not HWB1 or HWB2) (Conventional Design)
579
+ HWB4 Single Span - (Not HWB1 or HWB2) (Seismic Design)
580
+ HWB5 Concrete, Multi-Column Bent, Simple Support (Conventional Design), Non-California (Non CA)
581
+ HWB6 Concrete, Multi-Column Bent, Simple Support (Conventional Design), California (CA)
582
+ HWB7 Concrete, Multi-Column Bent, Simple Support (Seismic Design)
583
+ HWB8 Continuous Concrete, Single Column, Box Girder (Conventional Design)
584
+ HWB9 Continuous Concrete, Single Column, Box Girder (Seismic Design)
585
+ HWB10 Continuous Concrete, (Not HWB8 or HWB9) (Conventional Design)
586
+ HWB11 Continuous Concrete, (Not HWB8 or HWB9) (Seismic Design)
587
+ HWB12 Steel, Multi-Column Bent, Simple Support (Conventional Design), Non-California (Non-CA)
588
+ HWB13 Steel, Multi-Column Bent, Simple Support (Conventional Design), California (CA)
589
+ HWB14 Steel, Multi-Column Bent, Simple Support (Seismic Design)
590
+ HWB15 Continuous Steel (Conventional Design)
591
+ HWB16 Continuous Steel (Seismic Design)
592
+ HWB17 PS Concrete Multi-Column Bent, Simple Support (Conventional Design), Non-California
593
+ HWB18 PS Concrete, Multi-Column Bent, Simple Support (Conventional Design), California (CA)
594
+ HWB19 PS Concrete, Multi-Column Bent, Simple Support (Seismic Design)
595
+ HWB20 PS Concrete, Single Column, Box Girder (Conventional Design)
596
+ HWB21 PS Concrete, Single Column, Box Girder (Seismic Design)
597
+ HWB22 Continuous Concrete, (Not HWB20/HWB21) (Conventional Design)
598
+ HWB23 Continuous Concrete, (Not HWB20/HWB21) (Seismic Design)
599
+ HWB24 Same definition as HWB12 except the bridge length is less than 20 meters
600
+ HWB25 Same definition as HWB13 except the bridge length is less than 20 meters
601
+ HWB26 Same definition as HWB15 except the bridge length is less than 20 meters and Non-CA
602
+ HWB27 Same definition as HWB15 except the bridge length is less than 20 meters and in CA
603
+ HWB28 All other bridges that are not classified (including wooden bridges)
604
+
516
605
  """
517
606
  year_built = properties["year_built"]
518
607
  span_count = properties["span_count"]