docs: def get_risk_models(oqparam, kind='vulnerability vulnerability_retrofitted '
                      'fragility consequence'):
      """
      :param oqparam:
          an OqParam instance
      :param kind:
          a space-separated string with the kinds of risk models to read
      :returns:
          a dictionary riskid -> loss_type, kind -> function
      """
      kinds = kind.split()
      rmodels = AccumDict()
      for kind in kinds:
          for key in sorted(oqparam.inputs):
              mo = re.match('(occupants|%s)_%s$' % (COST_TYPE_REGEX, kind), key)
              if mo:
                  loss_type = mo.group(1)  # the cost_type in the key
                  # can be occupants, structural, nonstructural, ...
                  rmodel = nrml.to_python(oqparam.inputs[key])
                  if len(rmodel) == 0:
                      raise InvalidFile('%s is empty!' % oqparam.inputs[key])
                  rmodels[loss_type, kind] = rmodel
                  if rmodel.lossCategory is None:  # NRML 0.4
                      continue
                  cost_type = str(rmodel.lossCategory)
                  rmodel_kind = rmodel.__class__.__name__
                  kind_ = kind.replace('_retrofitted', '')  # strip retrofitted
                  if not rmodel_kind.lower().startswith(kind_):
                      raise ValueError(
                          'Error in the file "%s_file=%s": is '
                          'of kind %s, expected %s' % (
                              key, oqparam.inputs[key], rmodel_kind,
                              kind.capitalize() + 'Model'))
                  if cost_type != loss_type:
                      raise ValueError(
                          'Error in the file "%s_file=%s": lossCategory is of '
                          'type "%s", expected "%s"' %
                          (key, oqparam.inputs[key],
                           rmodel.lossCategory, loss_type))
      rdict = AccumDict(accum={})
      rdict.limit_states = []
      for (loss_type, kind), rm in sorted(rmodels.items()):
          if kind == 'fragility':
              # build a copy of the FragilityModel with different IM levels
              newfm = rm.build(oqparam.continuous_fragility_discretization,
                               oqparam.steps_per_interval)
              for (imt, riskid), ffl in newfm.items():
                  if not rdict.limit_states:
                      rdict.limit_states.extend(rm.limitStates)
                  # we are rejecting the case of loss types with different
                  # limit states; this may change in the future
                  assert rdict.limit_states == rm.limitStates, (
                      rdict.limit_states, rm.limitStates)
                  rdict[riskid][loss_type, kind] = ffl
                  # TODO: see if it is possible to remove the attribute
                  # below, used in classical_damage
                  ffl.steps_per_interval = oqparam.steps_per_interval
          elif kind == 'consequence':
              for riskid, cf in rm.items():
                  rdict[riskid][loss_type, kind] = cf
          else:  # vulnerability
              cl_risk = oqparam.calculation_mode in (
                  'classical', 'classical_risk')
              # only for classical_risk reduce the loss_ratios
              # to make sure they are strictly increasing
              for (imt, riskid), rf in rm.items():
                  rdict[riskid][loss_type, kind] = (
                      rf.strictly_increasing() if cl_risk else rf)
      return rdict