docs: def get_critical_line_loading(grid):
      """
      Assign line loading to each branch determined by peak load and peak
      generation of descendant branches
  
      The attribute `s_res` is a list of two elements
      1. apparent power in load case
      2. apparent power in feed-in case
  
      Parameters
      ----------
      grid : ding0.core.network.grids.LVGridDing0
          Ding0 LV grid object
  
      Returns
      -------
      :any:`list`
          List of critical branches incl. its line loading
      :any:`list`
          List of critical stations incl. its transformer loading
      """
      cos_phi_load = cfg_ding0.get('assumptions', 'cos_phi_load')
      cos_phi_feedin = cfg_ding0.get('assumptions', 'cos_phi_gen')
      lf_trafo_load = cfg_ding0.get('assumptions',
                                    "load_factor_lv_trans_lc_normal")
      lf_trafo_gen = cfg_ding0.get('assumptions',
                                    "load_factor_lv_trans_fc_normal")
  
      critical_branches = []
      critical_stations = []
  
      # Convert grid to a tree (is a directed graph)
      # based on this tree, descendants of each node are accessible
      station = grid._station
  
      tree = nx.dfs_tree(grid._graph, station)
  
      for node in tree.nodes():
  
          # list of descendant nodes including the node itself
          descendants = list(nx.descendants(tree, node))
          descendants.append(node)
  
          if isinstance(node, LVStationDing0):
              # determine cumulative peak load at node and assign to branch
              peak_load, peak_gen = peak_load_generation_at_node(descendants)
  
              if grid.id_db == 61107:
                  if isinstance(node, LVStationDing0):
                      print(node)
              # get trafos cumulative apparent power
              s_max_trafos = sum([_.s_max_a for _ in node._transformers])
  
              # compare with load and generation connected to
              if (((peak_load / cos_phi_load) > s_max_trafos * lf_trafo_load) or
                      ((peak_gen / cos_phi_feedin) > s_max_trafos * lf_trafo_gen)):
                  critical_stations.append(
                      {'station': node,
                       's_max': [
                           peak_load / cos_phi_load,
                           peak_gen / cos_phi_feedin]})
  
          else:
              # preceeding node of node
              predecessors = list(tree.predecessors(node))
  
              # a non-meshed grid topology returns a list with only 1 item
              predecessor = predecessors[0]
  
              # get preceeding
              branches = grid.graph_branches_from_node(node)
              preceeding_branch = [branch for branch in branches
                                   if branch[0] is predecessor][0]
  
              # determine cumulative peak load at node and assign to branch
              peak_load, peak_gen = peak_load_generation_at_node(descendants)
  
              s_max_th = 3 ** 0.5 * preceeding_branch[1]['branch'].type['U_n'] * \
                         preceeding_branch[1]['branch'].type['I_max_th'] / 1e3
  
              if (((peak_load / cos_phi_load) > s_max_th) or
                      ((peak_gen / cos_phi_feedin) > s_max_th)):
                  critical_branches.append(
                      {'branch': preceeding_branch[1]['branch'],
                       's_max': [
                           peak_load / cos_phi_load,
                           peak_gen / cos_phi_feedin]})
  
      return critical_branches, critical_stations