Skip to content

KeyError in classical_risk for multiple sites when using precomputed hazard curves #11619

Description

@LanaTodorovic93

OpenQuake Forum: https://groups.google.com/g/openquake-users/c/hEw7jPbxkTc

When the input hazard.csv file is formatted correctly (see job.zip), the following error appears:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\ltodorovic\openquake\Scripts\oq.exe\__main__.py", line 6, in <module>
  File "C:\Users\ltodorovic\GEM\oq-engine\openquake\commands\__main__.py", line 46, in oq
    sap.run(commands, prog='oq')
  File "C:\Users\ltodorovic\GEM\oq-engine\openquake\baselib\sap.py", line 233, in run
    return _run(parser(obj, **parserkw), argv)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\ltodorovic\GEM\oq-engine\openquake\baselib\sap.py", line 218, in _run
    return func(**dic)
           ^^^^^^^^^^^
  File "C:\Users\ltodorovic\GEM\oq-engine\openquake\commands\engine.py", line 176, in main
    run_jobs(jobs, nodes=nodes, sbatch=True,
  File "C:\Users\ltodorovic\GEM\oq-engine\openquake\engine\engine.py", line 424, in run_jobs
    _run(jobctxs, job_id, nodes, sbatch, concurrent_jobs, notify_to)
  File "C:\Users\ltodorovic\GEM\oq-engine\openquake\engine\engine.py", line 350, in _run
    run_calc(jobctx)
  File "C:\Users\ltodorovic\GEM\oq-engine\openquake\engine\engine.py", line 222, in run_calc
    calc.run(shutdown=True)
  File "C:\Users\ltodorovic\GEM\oq-engine\openquake\calculators\base.py", line 344, in run
    self.pre_execute()
  File "C:\Users\ltodorovic\GEM\oq-engine\openquake\calculators\classical_risk.py", line 101, in pre_execute
    self.riskinputs = self.build_riskinputs()
                      ^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\ltodorovic\GEM\oq-engine\openquake\calculators\base.py", line 1303, in build_riskinputs
    riskinputs = self._gen_riskinputs(dstore)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\ltodorovic\GEM\oq-engine\openquake\calculators\base.py", line 1313, in _gen_riskinputs
    getterdict = getters.CurveGetter.build(dstore)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\ltodorovic\GEM\oq-engine\openquake\calculators\getters.py", line 253, in build
    array = mgetter.init()
            ^^^^^^^^^^^^^^
  File "C:\Users\ltodorovic\GEM\oq-engine\openquake\calculators\getters.py", line 342, in init
    idxs = U32([sid2idx[sid] for sid in df.sid])
KeyError: 1

When hazard_curves_file is provided, base.py stores all hazard rates in _rates and registers a single slice and this creates one entry (see below):

oq show _rates/slice_by_idx -1
| idx | start | stop |
|-----+-------+------|
| 0   | 0     | 60   |

Separately, map_getters() in getters.py decides how to split work into chunks:

ct2 = concurrent_tasks // 2 or 1     
if N < ct2:
    return N                          # one chunk per site

With the concurrent_tasks=16 and 3 sites (from job.zip), this creates 3 chunks. Sites are assigned via sids % n == chunk, so chunk 0 gets site 0, chunk 1 gets site 1, chunk 2 gets site 2.
Chunk 0 queries idx == 0, which matches the single stored slice, so it reads the entire _rates table containing data for all 3 sites. But sid2idx is built only from chunk 0's site. When it encounters site 1 in the dataframe: KeyError: 1. The error persists for both regimes (https://github.com/gem/oq-engine/blob/master/openquake/calculators/getters.py#L157):

  • few sites, num_chunks=N
  • regular, num_chunks=concurrent_tasks/2

A possible solution is to filter the dataframe in MapGetter.init() so that each chunk keeps only its own sites and ignores the rest:

df = dstore.read_df('_rates', slc=slice(start, stop))
df = df[df.sid.isin(sid2idx)]  # add this line
idxs = U32([sid2idx[sid] for sid in df.sid])

job.zip

Metadata

Metadata

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions