Use command line parameter for location in a project bookmark

How can I use a command line parameter to change the location of a file in a bookmark?

[bookmark tanks]
location = Data/notAFile.csv
set-attribute.latitude = Lat_HH
set-attribute.longitude = Long_HH
set-attribute.HH_tot = HH_tot
set-attribute.UtArea_rf = UtArea_rf
set-attribute.tank_vol = tank_vol
set-attribute.tank_cond = tank_cond
set-attribute.geom = create_point(Long_HH,Lat_HH)
crs-name = EPSG:4326


powellj@localhost ~/versioned/riskscape-shiny-app/trunk/code $ riskscape model run finalTotals  -p "tanks.location='Data/RMITanksTrimmed.csv'"
[WARNING] Surplus parameters were given that were ignored: [tanks.location], did you mean one of [tankWaterFolder]?
Failed to validate model for execution
  - Failed to validate 'input(relation: 'tanks', name: 'exposure') as exposures_input' step for execution
    - Problems found with 'relation' parameter
      - Problems found with 'tanks' bookmark in location file:///home/powellj/versioned/riskscape-shiny-app/trunk/code/Data/notAFile.csv
        - File '/home/powellj/versioned/riskscape-shiny-app/trunk/code/Data/notAFile.csv' does not exist

I want users to be able to specify the name of their input csv without having to resupply the set-attribute commands that are in the bookmark.

In this case, you put the location into the pipeline itself, rather than the bookmark. The bookmark() function takes a second options argument that lets you override any of the bookmark’s parameters, including the file location. So your model would start off something like:

input(bookmark('tanks', {location: $tanks_location}))

Thanks Tim that worked perfectly

Is it possible to also do this with filters?

I have the bookmark

location = Farms.shp
format = shapefile
filter = region = 'AUCK'


input(relation: bookmark('Farms', {filter: $region_filter}), name: 'exposure') as exposures_input

in my pipeline

When I run with

riskscape model run FloodExposure -p "region_filter = region = 'CANT'"

I get

powellj@localhost ~ $ riskscape -e model run FloodExposure -p "region_filter = region = 'CANT'"
Failed to validate model for execution
  - Failed to validate 'input(relation: bookmark('Farms', {filter: region = 'CANT'}), name: 'exposure') as exposures_input' step for execution
    - Parameter 'relation' requires value, but expression 'bookmark('Farms', {filter: region = 'CANT'})' cannot be realized
      - Expected expression 'region' to be a Struct, but got Nullable[Anything] instead
      - Problems found with 'bookmark' riskscape function
        - Argument 'type' is required Problem(ERROR: CANNOT_REALIZE['interface'] affected=interface[Problem(ERROR: CANNOT_REALIZE['exposures_input:[input]'] affected=exposures_input:[input]children=[Problem(ERROR: PARAMETER_EXPRESSION_NOT_REALIZABLE['relation', 'bookmark('Farms', {filter: region = 'CANT'})']children=[Problem(ERROR: NOT_STRUCT['PropertyAccess[region]', 'Nullable[Anything]'] affected=PropertyAccess[region]), Problem(ERROR: PROBLEMS_FOUND[''bookmark' riskscapefunction'] affected=interface[Problem(ERROR: REQUIRED['type'] affected=type)])])])])

I can see the type it is getting back is not what it wants but I dont know how to change that

This does work fine if I remove the filter expression from in the pipeline and just have it in the bookmark IE it correctly runs with just AUCK data.

OK, that error message has got me stumped as well.

However, a simpler way to do it would be to just remove the filter from the bookmark and add it as a pipeline step instead. E.g.

input('Farms', name: 'exposure') -> filter($region_filter)

That should work, and do essentially the same thing. Note that you will need to add exposure to the parameter now, so it will become something like: -p "region_filter = exposure.region = 'CANT'". It’s a bit more to type, but this approach still lets you incalude all regions (i.e. filter nothing), e.g. -p "region_filter=true".

If you’re always going to filter out one region, then you could just make the region name the parameter, e.g.

input('Farms', name: 'exposure') -> filter(exposure.region = $region)

Then you can call your model just with -p "region='CANT'".

I’ll investigate some more why what you were originally trying to do doesn’t work and let you know.

So I don’t fully understand why, but your original pipeline will work if you pass the filter expression through as a text string, e.g.

riskscape model run FloodExposure -p "region_filter = 'region = \'CANT\''"

I think this is just a limitation with the current support for parameterized pipelines. We do have a ticket in the backlog to improve this in future.

I’d recommend using the separate filter step approach in my previous post though, as I think that’s simpler to understand/get right.