@@ -217,6 +217,13 @@ def make_source_event_item(self, pdc_hazard_data: HazardEventValidator, pdc_expo
217217 monty .country_codes = list (set (all_iso3 ))
218218
219219 monty .hazard_codes = self ._map_pdc_to_hazard_codes (hazard = pdc_hazard_data .type_ID )
220+ monty .hazard_codes = self .hazard_profiles .get_canonical_hazard_codes (item = item )
221+
222+ # Generate keywords for discoverability
223+ hazard_keywords = self .hazard_profiles .get_keywords (monty .hazard_codes )
224+ country_keywords = [obj .admin0 for obj in pdc_exposure_data .totalByCountry ] if pdc_exposure_data .totalByCountry else []
225+ item .properties ["keywords" ] = list (set (hazard_keywords + country_keywords ))
226+
220227 # TODO: Deal with correlation id if country_codes is a empty list
221228 if monty .country_codes :
222229 monty .compute_and_set_correlation_id (hazard_profiles = self .hazard_profiles )
@@ -229,31 +236,64 @@ def make_source_event_item(self, pdc_hazard_data: HazardEventValidator, pdc_expo
229236 return item
230237
231238 def _map_pdc_to_hazard_codes (self , hazard : str ) -> List [str ] | None :
232- """Maps the hazard to the standard UNDRR-ISC 2020 Hazard Codes"""
233- hazard_mapping = {
234- "AVALANCHE" : ["MH0050" , "nat-geo-mmd-ava" ],
235- "DROUGHT" : ["MH0035" , "nat-cli-dro-dro" ],
236- "EARTHQUAKE" : ["GH0001" , "nat-geo-ear-gro" ],
237- "EXTREMETEMPERATURE" : ["MH0040" , "MH0047" , "MH0041" , "nat-met-ext-col" , "nat-met-ext-hea" , "nat-met-ext-sev" ],
238- "FLOOD" : ["MH0012" , "nat-hyd-flo-flo" ],
239- "HIGHWIND" : ["MH0060" , "nat-met-sto-sto" ],
240- "LANDSLIDE" : ["nat-geo-mmd-lan" ],
241- "SEVEREWEATHER" : ["nat-met-sto-sev" ],
242- "STORM" : ["nat-met-sto-bli" ],
243- "TORNADO" : ["nat-met-sto-tor" ],
244- "CYCLONE" : ["nat-met-sto-tro" ],
245- "TSUNAMI" : ["MH0029" , "nat-geo-ear-tsu" ],
246- "VOLCANO" : ["GH0020" , "nat-geo-vol-vol" ],
247- "WILDFIRE" : ["EN0013" , "nat-cli-wil-for" ],
248- "WINTERSTORM" : ["nat-met-sto-bli" ],
249- "STORMSURGE" : ["MH0027" , "nat-met-sto-sur" ],
239+ """
240+ Map PDC hazard types to standard classification codes.
241+ Returns codes in order: [UNDRR-ISC 2025, EM-DAT, GLIDE]
242+
243+ The UNDRR-ISC 2025 code is the reference classification for the Monty extension.
244+ All three codes are included for maximum interoperability.
245+
246+ Args:
247+ hazard: PDC hazard type (e.g., 'EARTHQUAKE', 'FLOOD')
248+
249+ Returns:
250+ List of classification codes or None if not found
251+ """
252+ # Natural Hazards
253+ natural_hazards = {
254+ "AVALANCHE" : ["MH0801" , "nat-hyd-mmw-ava" , "AV" ],
255+ "BIOMEDICAL" : ["BI0101" , "nat-bio-epi-dis" , "EP" ],
256+ "DROUGHT" : ["MH0401" , "nat-cli-dro-dro" , "DR" ],
257+ "EARTHQUAKE" : ["GH0101" , "nat-geo-ear-gro" , "EQ" ],
258+ "EXTREMETEMPERATURE" : ["MH0501" , "nat-met-ext-hea" , "HT" ], # Default to heat, may need logic for cold
259+ "FLOOD" : ["MH0600" , "nat-hyd-flo-flo" , "FL" ],
260+ "HIGHSURF" : ["MH0702" , "nat-hyd-wav-wav" , "OT" ],
261+ "LANDSLIDE" : ["GH0300" , "nat-geo-mmd-lan" , "LS" ],
262+ "MARINE" : ["MH0700" , "nat-hyd-wav-wav" , "OT" ],
263+ "SEVEREWEATHER" : ["MH0103" , "nat-met-sto-sto" , "ST" ],
264+ "STORM" : ["MH0103" , "nat-met-sto-sto" , "ST" ],
265+ "TORNADO" : ["MH0305" , "nat-met-sto-tor" , "TO" ],
266+ "CYCLONE" : ["MH0306" , "nat-met-sto-tro" , "TC" ],
267+ "TSUNAMI" : ["MH0705" , "nat-geo-ear-tsu" , "TS" ],
268+ "VOLCANO" : ["GH0201" , "nat-geo-vol-vol" , "VO" ],
269+ "WILDFIRE" : ["EN0205" , "nat-cli-wil-for" , "WF" ],
270+ "WINTERSTORM" : ["MH0403" , "nat-met-sto-bli" , "OT" ],
250271 }
251272
273+ # Geopolitical & Technological Hazards
274+ tech_social_hazards = {
275+ "ACCIDENT" : ["TL0200" , "tec-mis-col-col" , "AC" ],
276+ "ACTIVESHOOTER" : ["SO0201" , "soc-soc-vio-vio" , "OT" ],
277+ "CIVILUNREST" : ["SO0202" , "soc-soc-vio-vio" , "OT" ],
278+ "COMBAT" : ["SO0201" , "soc-soc-vio-vio" , "OT" ],
279+ "CYBER" : ["TL0601" , "" , "OT" ], # No EM-DAT equivalent
280+ "MANMADE" : ["TL0000" , "tec-tec-tec-tec" , "OT" ],
281+ "OCCURRENCE" : ["OT0000" , "" , "OT" ], # No EM-DAT equivalent
282+ "POLITICALCONFLICT" : ["SO0201" , "soc-soc-vio-vio" , "OT" ],
283+ "TERRORISM" : ["SO0203" , "soc-soc-vio-vio" , "OT" ],
284+ "WEAPONS" : ["SO0201" , "soc-soc-vio-vio" , "OT" ],
285+ }
286+
287+ # Combine all mappings
288+ hazard_mapping = {** natural_hazards , ** tech_social_hazards }
289+
252290 if hazard not in hazard_mapping :
253- logger .warning (f"The hazard { hazard } is not in the mapping." )
291+ logger .warning (f"PDC hazard type ' { hazard } ' not found in UNDRR-ISC 2025 mapping." )
254292 return None
255293
256- return hazard_mapping .get (hazard )
294+ codes = hazard_mapping .get (hazard )
295+ # Filter out empty strings (for codes without EM-DAT equivalents)
296+ return [code for code in codes if code ] if codes else None
257297
258298 def make_hazard_item (self , event_item : Item , hazard_data : HazardEventValidator ) -> Item :
259299 """Create Hazard Item"""
@@ -266,10 +306,10 @@ def make_hazard_item(self, event_item: Item, hazard_data: HazardEventValidator)
266306 hazard_item .set_collection (self .get_hazard_collection ())
267307
268308 monty = MontyExtension .ext (hazard_item )
309+ monty .hazard_codes = [self .hazard_profiles .get_undrr_2025_code (hazard_codes = monty .hazard_codes )]
269310 # Hazard Detail
270311 monty .hazard_detail = HazardDetail (
271- cluster = self .hazard_profiles .get_cluster_code (hazard_item ),
272- severity_value = None ,
312+ severity_value = 0.1 , # 0.1 is passed inorder to pass validation it means None in this case
273313 severity_unit = "PDC Severity Score" ,
274314 severity_label = hazard_data .severity_ID ,
275315 estimate_type = MontyEstimateType .PRIMARY ,
0 commit comments