docs: def reduce(fname, reduction_factor):
      """
      Produce a submodel from `fname` by sampling the nodes randomly.
      Supports source models, site models and exposure models. As a special
      case, it is also able to reduce .csv files by sampling the lines.
      This is a debugging utility to reduce large computations to small ones.
      """
      if fname.endswith('.csv'):
          with open(fname) as f:
              line = f.readline()  # read the first line
              if csv.Sniffer().has_header(line):
                  header = line
                  all_lines = f.readlines()
              else:
                  header = None
                  f.seek(0)
                  all_lines = f.readlines()
          lines = general.random_filter(all_lines, reduction_factor)
          shutil.copy(fname, fname + '.bak')
          print('Copied the original file in %s.bak' % fname)
          _save_csv(fname, lines, header)
          print('Extracted %d lines out of %d' % (len(lines), len(all_lines)))
          return
      elif fname.endswith('.npy'):
          array = numpy.load(fname)
          shutil.copy(fname, fname + '.bak')
          print('Copied the original file in %s.bak' % fname)
          arr = numpy.array(general.random_filter(array, reduction_factor))
          numpy.save(fname, arr)
          print('Extracted %d rows out of %d' % (len(arr), len(array)))
          return
      node = nrml.read(fname)
      model = node[0]
      if model.tag.endswith('exposureModel'):
          total = len(model.assets)
          model.assets.nodes = general.random_filter(
              model.assets, reduction_factor)
          num_nodes = len(model.assets)
      elif model.tag.endswith('siteModel'):
          total = len(model)
          model.nodes = general.random_filter(model, reduction_factor)
          num_nodes = len(model)
      elif model.tag.endswith('sourceModel'):
          reduce_source_model(fname, reduction_factor)
          return
      elif model.tag.endswith('logicTree'):
          for smpath in logictree.collect_info(fname).smpaths:
              reduce_source_model(smpath, reduction_factor)
          return
      else:
          raise RuntimeError('Unknown model tag: %s' % model.tag)
      save_bak(fname, node, num_nodes, total)