docs: def get_vulnerability_functions_04(fname):
      """
      Parse the vulnerability model in NRML 0.4 format.
  
      :param fname:
          path of the vulnerability file
      :returns:
          a dictionary imt, taxonomy -> vulnerability function + vset
      """
      categories = dict(assetCategory=set(), lossCategory=set(),
                        vulnerabilitySetID=set())
      imts = set()
      taxonomies = set()
      vf_dict = {}  # imt, taxonomy -> vulnerability function
      for vset in nrml.read(fname).vulnerabilityModel:
          categories['assetCategory'].add(vset['assetCategory'])
          categories['lossCategory'].add(vset['lossCategory'])
          categories['vulnerabilitySetID'].add(vset['vulnerabilitySetID'])
          IML = vset.IML
          imt_str = IML['IMT']
          imls = ~IML
          imts.add(imt_str)
          for vfun in vset.getnodes('discreteVulnerability'):
              taxonomy = vfun['vulnerabilityFunctionID']
              if taxonomy in taxonomies:
                  raise InvalidFile(
                      'Duplicated vulnerabilityFunctionID: %s: %s, line %d' %
                      (taxonomy, fname, vfun.lineno))
              taxonomies.add(taxonomy)
              with context(fname, vfun):
                  loss_ratios = ~vfun.lossRatio
                  coefficients = ~vfun.coefficientsVariation
              if len(loss_ratios) != len(imls):
                  raise InvalidFile(
                      'There are %d loss ratios, but %d imls: %s, line %d' %
                      (len(loss_ratios), len(imls), fname,
                       vfun.lossRatio.lineno))
              if len(coefficients) != len(imls):
                  raise InvalidFile(
                      'There are %d coefficients, but %d imls: %s, line %d' %
                      (len(coefficients), len(imls), fname,
                       vfun.coefficientsVariation.lineno))
              with context(fname, vfun):
                  vf_dict[imt_str, taxonomy] = scientific.VulnerabilityFunction(
                      taxonomy, imt_str, imls, loss_ratios, coefficients,
                      vfun['probabilisticDistribution'])
      categories['id'] = '_'.join(sorted(categories['vulnerabilitySetID']))
      del categories['vulnerabilitySetID']
      return vf_dict, categories