Using a shapefile's attribute as the HIM

I’m working on a multi-hazard pipeline. The pipeline itself is operating fine for raster (.tif) hazard files, but for hazard shapefiles (.shp) it is reading in all the available attribute values, rather than just the attribute relavant to the hazard intensity measure (HIM) - ‘BUFF_DIST’ and ‘Min’ in my example. I have played around with navigating to, and defining, the HIM attribute in the shapefile (in the .py and in the .ini files) with no luck. I could solve this by converting my hazard shapefiles to a rasters, but I would rather figure this out for when I run into this again in future modelling.

What’s best practice for this?

Kia ora,

That’s actually a really good question. It gets a bit tricky to mix and match shapefile and raster hazards, especially with multi-hazard. There is support in the wizard for pulling a specific attribute out of vector hazard data or multi-hazard support, but I think you want both here.

Probably the simplest option would be to use set-attribute in your shapefile bookmark to set a common attribute name, e.g. ‘HIM’ in this example:

[bookmark Scenario A edifice ...]
location = Scenario_A_yada_yada.shp
set-attribute.HIM = BUFF_DIST

Then you could update your Python function to handle being passed either raster data (i.e. a floating-point number) or vector data (i.e. a RiskScape struct/Python dict), like this:

edifice_hazardValue = multihazard.get('edifice')
if type(edifice_hazardValue) is dict:
    edifice_hazardValue = edifice_hazardValue.get('HIM')

Let me know if that doesn’t work. I’ve assumed you’ve used the multi-hazard functionality in the wizard to build your model here, but there are other ways you might have done it.

BTW, unrelated, but you probably shouldn’t need all the crs-name = EPSG:32760 lines in your bookmarks. We recommend only using crs-name with CSV input data, or as a last resort if for some reason RiskScape cannot recognize the CRS in your input data.

Cheers,
Tim

Kia ora Tim,

Thanks for that, I have done as suggested, but there is no change to the output. You are corect in asuming I use the multi-hazard wizard functionality. The edifice_hazardValue has no data, I am printing it to the ‘consequence’ table and only blank values are printed.

Any other ideas?

Cheers,
James

OK, probably the most likely cause there is the RiskScape struct being passed to your Python function doesn’t quite match what you’d expect. Try changing the following lines in your Python code so they access the dictionary using square brackets instead of .get():

edifice_hazardValue = multihazard['edifice']
if type(edifice_hazardValue) is dict:
    edifice_hazardValue = edifice_hazardValue['HIM']

That will most result in a Python KeyError when you try to run your model. That would mean we’re on the right track, but doesn’t really tell us anything about what the data being passed to your function looks like.

There are a few ways to debug the data that your Python function is actually getting:

  • you can try adding some print() statements to your Python function to dump out details about the multihazard dictionary it is actually getting, e.g. print(multihazard.keys())
  • you can try adding --print to the end of your riskscape model run command and that will dump out the RiskScape types at every step of your model pipeline (a lot of information, but I can help you decipher it)
  • temporarily change your function definition in your project.ini to use deliberately bad arguments, e.g.
    # argument-types = [building: anything, multihazard: anything]
    argument-types = [building: anything, multihazard: text]
    
    When you try to run your model, the error will then tell you exactly what types your function is being called with. Just remember to revert the argument-types back to normal as soon as you get the error message.

Thanks Tim,
Managed to get things working with your advice, and it ended up being a pretty simple line that did the trick:

edifice_hazardValue = multihazard.get('edifice_HIM')