nodes: 0, module; 1, function_definition; 2, function_name:mv_voltage_deviation; 3, parameters; 4, block; 5, identifier:network; 6, default_parameter; 7, expression_statement; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, if_statement; 15, comment:# maximum allowed apparent power of station in each time step; 16, expression_statement; 17, expression_statement; 18, expression_statement; 19, expression_statement; 20, if_statement; 21, return_statement; 22, identifier:voltage_levels; 23, string; 24, comment:"""
      Checks for voltage stability issues in MV grid.
  
      Parameters
      ----------
      network : :class:`~.grid.network.Network`
      voltage_levels : :obj:`str`
          Specifies which allowed voltage deviations to use. Possible options
          are:
  
          * 'mv_lv'
            This is the default. The allowed voltage deviation for nodes in the
            MV grid is the same as for nodes in the LV grid. Further load and
            feed-in case are not distinguished.
          * 'mv'
            Use this to handle allowed voltage deviations in the MV and LV grid
            differently. Here, load and feed-in case are differentiated as well.
  
      Returns
      -------
      :obj:`dict`
          Dictionary with :class:`~.grid.grids.MVGrid` as key and a
          :pandas:`pandas.DataFrame<dataframe>` with its critical nodes, sorted
          descending by voltage deviation, as value.
          Index of the dataframe are all nodes (of type
          :class:`~.grid.components.Generator`, :class:`~.grid.components.Load`,
          etc.) with over-voltage issues. Columns are 'v_mag_pu' containing the
          maximum voltage deviation as float and 'time_index' containing the
          corresponding time step the over-voltage occured in as
          :pandas:`pandas.Timestamp<timestamp>`.
  
      Notes
      -----
      Over-voltage is determined based on allowed voltage deviations defined in
      the config file 'config_grid_expansion' in section
      'grid_expansion_allowed_voltage_deviations'.
  
      """; 25, assignment; 26, assignment; 27, assignment; 28, assignment; 29, assignment; 30, assignment; 31, comparison_operator:voltage_levels == 'mv_lv'; 32, block; 33, elif_clause; 34, else_clause; 35, assignment; 36, assignment; 37, assignment; 38, assignment; 39, not_operator; 40, block; 41, else_clause; 42, identifier:crit_nodes; 43, string_content:mv_lv; 44, identifier:crit_nodes; 45, dictionary; 46, identifier:v_dev_allowed_per_case; 47, dictionary; 48, subscript; 49, float:0.9; 50, subscript; 51, float:1.1; 52, identifier:offset; 53, subscript; 54, identifier:control_deviation; 55, subscript; 56, identifier:voltage_levels; 57, string; 58, expression_statement; 59, expression_statement; 60, comparison_operator:voltage_levels == 'mv'; 61, block; 62, block; 63, identifier:v_dev_allowed_upper; 64, line_continuation:\; 65, call; 66, identifier:v_dev_allowed_lower; 67, line_continuation:\; 68, call; 69, identifier:nodes; 70, call; 71, identifier:crit_nodes_grid; 72, call; 73, attribute; 74, expression_statement; 75, expression_statement; 76, block; 77, identifier:v_dev_allowed_per_case; 78, string; 79, identifier:v_dev_allowed_per_case; 80, string; 81, subscript; 82, string; 83, subscript; 84, string; 85, string_content:mv_lv; 86, assignment; 87, assignment; 88, identifier:voltage_levels; 89, string; 90, expression_statement; 91, expression_statement; 92, raise_statement; 93, attribute; 94, argument_list; 95, attribute; 96, argument_list; 97, attribute; 98, argument_list; 99, identifier:_voltage_deviation; 100, argument_list; 101, identifier:crit_nodes_grid; 102, identifier:empty; 103, assignment; 104, call; 105, expression_statement; 106, string_content:feedin_case_lower; 107, string_content:load_case_upper; 108, attribute; 109, string; 110, string_content:hv_mv_trafo_offset; 111, attribute; 112, string; 113, string_content:hv_mv_trafo_control_deviation; 114, subscript; 115, line_continuation:\; 116, binary_operator:1 + offset + control_deviation + network.config[
                  'grid_expansion_allowed_voltage_deviations'][
                  'mv_lv_feedin_case_max_v_deviation']; 117, subscript; 118, line_continuation:\; 119, binary_operator:1 + offset - control_deviation - network.config[
                  'grid_expansion_allowed_voltage_deviations'][
                  'mv_lv_load_case_max_v_deviation']; 120, string_content:mv; 121, assignment; 122, assignment; 123, call; 124, attribute; 125, identifier:apply; 126, lambda; 127, attribute; 128, identifier:apply; 129, lambda; 130, attribute; 131, identifier:nodes; 132, identifier:network; 133, identifier:nodes; 134, identifier:v_dev_allowed_upper; 135, identifier:v_dev_allowed_lower; 136, keyword_argument; 137, subscript; 138, call; 139, attribute; 140, argument_list; 141, call; 142, identifier:network; 143, identifier:config; 144, string_content:grid_expansion_allowed_voltage_deviations; 145, identifier:network; 146, identifier:config; 147, string_content:grid_expansion_allowed_voltage_deviations; 148, identifier:v_dev_allowed_per_case; 149, string; 150, binary_operator:1 + offset + control_deviation; 151, subscript; 152, identifier:v_dev_allowed_per_case; 153, string; 154, binary_operator:1 + offset - control_deviation; 155, subscript; 156, subscript; 157, line_continuation:\; 158, binary_operator:1 + offset + control_deviation + network.config[
                  'grid_expansion_allowed_voltage_deviations'][
                  'mv_feedin_case_max_v_deviation']; 159, subscript; 160, line_continuation:\; 161, binary_operator:1 + offset - control_deviation - network.config[
                  'grid_expansion_allowed_voltage_deviations'][
                  'mv_load_case_max_v_deviation']; 162, identifier:ValueError; 163, argument_list; 164, attribute; 165, identifier:case; 166, lambda_parameters; 167, subscript; 168, attribute; 169, identifier:case; 170, lambda_parameters; 171, subscript; 172, attribute; 173, identifier:graph; 174, identifier:voltage_level; 175, string; 176, identifier:crit_nodes; 177, attribute; 178, attribute; 179, argument_list; 180, identifier:logger; 181, identifier:debug; 182, call; 183, attribute; 184, argument_list; 185, string_content:feedin_case_upper; 186, binary_operator:1 + offset; 187, identifier:control_deviation; 188, subscript; 189, string; 190, string_content:load_case_lower; 191, binary_operator:1 + offset; 192, identifier:control_deviation; 193, subscript; 194, string; 195, identifier:v_dev_allowed_per_case; 196, string; 197, binary_operator:1 + offset + control_deviation; 198, subscript; 199, identifier:v_dev_allowed_per_case; 200, string; 201, binary_operator:1 + offset - control_deviation; 202, subscript; 203, call; 204, attribute; 205, identifier:timesteps_load_feedin_case; 206, identifier:_; 207, identifier:v_dev_allowed_per_case; 208, call; 209, attribute; 210, identifier:timesteps_load_feedin_case; 211, identifier:_; 212, identifier:v_dev_allowed_per_case; 213, call; 214, identifier:network; 215, identifier:mv_grid; 216, string_content:mv; 217, identifier:network; 218, identifier:mv_grid; 219, identifier:crit_nodes_grid; 220, identifier:sort_values; 221, keyword_argument; 222, keyword_argument; 223, attribute; 224, argument_list; 225, identifier:logger; 226, identifier:debug; 227, string; 228, integer:1; 229, identifier:offset; 230, attribute; 231, string; 232, string_content:mv_lv_feedin_case_max_v_deviation; 233, integer:1; 234, identifier:offset; 235, attribute; 236, string; 237, string_content:mv_lv_load_case_max_v_deviation; 238, string_content:feedin_case_upper; 239, binary_operator:1 + offset; 240, identifier:control_deviation; 241, subscript; 242, string; 243, string_content:load_case_lower; 244, binary_operator:1 + offset; 245, identifier:control_deviation; 246, subscript; 247, string; 248, attribute; 249, argument_list; 250, identifier:network; 251, identifier:timeseries; 252, attribute; 253, argument_list; 254, identifier:network; 255, identifier:timeseries; 256, attribute; 257, argument_list; 258, identifier:by; 259, list; 260, identifier:ascending; 261, False; 262, string; 263, identifier:format; 264, subscript; 265, string_content:==> No voltage issues in MV grid.; 266, identifier:network; 267, identifier:config; 268, string_content:grid_expansion_allowed_voltage_deviations; 269, identifier:network; 270, identifier:config; 271, string_content:grid_expansion_allowed_voltage_deviations; 272, integer:1; 273, identifier:offset; 274, attribute; 275, string; 276, string_content:mv_feedin_case_max_v_deviation; 277, integer:1; 278, identifier:offset; 279, attribute; 280, string; 281, string_content:mv_load_case_max_v_deviation; 282, string; 283, identifier:format; 284, identifier:voltage_levels; 285, string; 286, identifier:format; 287, identifier:_; 288, string; 289, identifier:format; 290, identifier:_; 291, string; 292, string_content:==> {} node(s) in MV grid has/have voltage issues.; 293, attribute; 294, integer:0; 295, identifier:network; 296, identifier:config; 297, string_content:grid_expansion_allowed_voltage_deviations; 298, identifier:network; 299, identifier:config; 300, string_content:grid_expansion_allowed_voltage_deviations; 301, string_content:Specified mode {} is not a valid option.; 302, string_content:{}_upper; 303, string_content:{}_lower; 304, string_content:v_mag_pu; 305, subscript; 306, identifier:shape; 307, identifier:crit_nodes; 308, attribute; 309, identifier:network; 310, identifier:mv_grid
code: def mv_voltage_deviation(network, voltage_levels='mv_lv'):
      """
      Checks for voltage stability issues in MV grid.
  
      Parameters
      ----------
      network : :class:`~.grid.network.Network`
      voltage_levels : :obj:`str`
          Specifies which allowed voltage deviations to use. Possible options
          are:
  
          * 'mv_lv'
            This is the default. The allowed voltage deviation for nodes in the
            MV grid is the same as for nodes in the LV grid. Further load and
            feed-in case are not distinguished.
          * 'mv'
            Use this to handle allowed voltage deviations in the MV and LV grid
            differently. Here, load and feed-in case are differentiated as well.
  
      Returns
      -------
      :obj:`dict`
          Dictionary with :class:`~.grid.grids.MVGrid` as key and a
          :pandas:`pandas.DataFrame<dataframe>` with its critical nodes, sorted
          descending by voltage deviation, as value.
          Index of the dataframe are all nodes (of type
          :class:`~.grid.components.Generator`, :class:`~.grid.components.Load`,
          etc.) with over-voltage issues. Columns are 'v_mag_pu' containing the
          maximum voltage deviation as float and 'time_index' containing the
          corresponding time step the over-voltage occured in as
          :pandas:`pandas.Timestamp<timestamp>`.
  
      Notes
      -----
      Over-voltage is determined based on allowed voltage deviations defined in
      the config file 'config_grid_expansion' in section
      'grid_expansion_allowed_voltage_deviations'.
  
      """
  
      crit_nodes = {}
  
      v_dev_allowed_per_case = {}
      v_dev_allowed_per_case['feedin_case_lower'] = 0.9
      v_dev_allowed_per_case['load_case_upper'] = 1.1
      offset = network.config[
          'grid_expansion_allowed_voltage_deviations']['hv_mv_trafo_offset']
      control_deviation = network.config[
          'grid_expansion_allowed_voltage_deviations'][
          'hv_mv_trafo_control_deviation']
      if voltage_levels == 'mv_lv':
          v_dev_allowed_per_case['feedin_case_upper'] = \
              1 + offset + control_deviation + network.config[
                  'grid_expansion_allowed_voltage_deviations'][
                  'mv_lv_feedin_case_max_v_deviation']
          v_dev_allowed_per_case['load_case_lower'] = \
              1 + offset - control_deviation - network.config[
                  'grid_expansion_allowed_voltage_deviations'][
                  'mv_lv_load_case_max_v_deviation']
      elif voltage_levels == 'mv':
          v_dev_allowed_per_case['feedin_case_upper'] = \
              1 + offset + control_deviation + network.config[
                  'grid_expansion_allowed_voltage_deviations'][
                  'mv_feedin_case_max_v_deviation']
          v_dev_allowed_per_case['load_case_lower'] = \
              1 + offset - control_deviation - network.config[
                  'grid_expansion_allowed_voltage_deviations'][
                  'mv_load_case_max_v_deviation']
      else:
          raise ValueError(
              'Specified mode {} is not a valid option.'.format(voltage_levels))
      # maximum allowed apparent power of station in each time step
      v_dev_allowed_upper = \
          network.timeseries.timesteps_load_feedin_case.case.apply(
              lambda _: v_dev_allowed_per_case['{}_upper'.format(_)])
      v_dev_allowed_lower = \
          network.timeseries.timesteps_load_feedin_case.case.apply(
              lambda _: v_dev_allowed_per_case['{}_lower'.format(_)])
  
      nodes = network.mv_grid.graph.nodes()
  
      crit_nodes_grid = _voltage_deviation(
          network, nodes, v_dev_allowed_upper, v_dev_allowed_lower,
          voltage_level='mv')
  
      if not crit_nodes_grid.empty:
          crit_nodes[network.mv_grid] = crit_nodes_grid.sort_values(
              by=['v_mag_pu'], ascending=False)
          logger.debug(
              '==> {} node(s) in MV grid has/have voltage issues.'.format(
                  crit_nodes[network.mv_grid].shape[0]))
      else:
          logger.debug('==> No voltage issues in MV grid.')
  
      return crit_nodes