nodes: 0, module; 1, function_definition; 2, function_name:make_general; 3, parameters; 4, block; 5, identifier:basis; 6, default_parameter; 7, expression_statement; 8, expression_statement; 9, expression_statement; 10, for_statement; 11, return_statement; 12, identifier:use_copy; 13, True; 14, comment:"""
      Makes one large general contraction for each angular momentum
  
      If use_copy is True, the input basis set is not modified.
  
      The output of this function is not pretty. If you want to make it nicer,
      use sort_basis afterwards.
      """; 15, assignment; 16, assignment; 17, pattern_list; 18, call; 19, block; 20, identifier:basis; 21, identifier:zero; 22, string; 23, identifier:basis; 24, call; 25, identifier:k; 26, identifier:el; 27, attribute; 28, argument_list; 29, if_statement; 30, comment:# See what we have; 31, expression_statement; 32, for_statement; 33, expression_statement; 34, expression_statement; 35, for_statement; 36, expression_statement; 37, string_content:0.00000000; 38, identifier:uncontract_spdf; 39, argument_list; 40, subscript; 41, identifier:items; 42, not_operator; 43, block; 44, assignment; 45, identifier:sh; 46, subscript; 47, block; 48, assignment; 49, assignment; 50, identifier:am; 51, identifier:all_am; 52, block; 53, assignment; 54, identifier:basis; 55, integer:0; 56, identifier:use_copy; 57, identifier:basis; 58, string; 59, comparison_operator:'electron_shells' in el; 60, continue_statement; 61, identifier:all_am; 62, list; 63, identifier:el; 64, string; 65, if_statement; 66, identifier:all_am; 67, call; 68, identifier:newshells; 69, list; 70, expression_statement; 71, comment:# Do exponents first; 72, for_statement; 73, comment:# Number of primitives in the new shell; 74, expression_statement; 75, expression_statement; 76, for_statement; 77, expression_statement; 78, subscript; 79, identifier:newshells; 80, string_content:elements; 81, string; 82, identifier:el; 83, string_content:electron_shells; 84, not_operator; 85, block; 86, identifier:sorted; 87, argument_list; 88, assignment; 89, identifier:sh; 90, subscript; 91, block; 92, assignment; 93, assignment; 94, identifier:sh; 95, subscript; 96, block; 97, call; 98, identifier:el; 99, string; 100, string_content:electron_shells; 101, comparison_operator:sh['angular_momentum'] in all_am; 102, expression_statement; 103, identifier:all_am; 104, identifier:newsh; 105, dictionary; 106, identifier:el; 107, string; 108, if_statement; 109, expression_statement; 110, identifier:nprim; 111, call; 112, identifier:cur_prim; 113, integer:0; 114, identifier:el; 115, string; 116, if_statement; 117, if_statement; 118, comment:# Make sure the shells we are merging have the same function types; 119, expression_statement; 120, expression_statement; 121, comment:# Check if one function type is the subset of another; 122, comment:# (should handle gto/gto_spherical, etc); 123, if_statement; 124, expression_statement; 125, for_statement; 126, expression_statement; 127, attribute; 128, argument_list; 129, string_content:electron_shells; 130, subscript; 131, identifier:all_am; 132, call; 133, pair; 134, pair; 135, pair; 136, pair; 137, pair; 138, string_content:electron_shells; 139, comparison_operator:sh['angular_momentum'] != am; 140, block; 141, call; 142, identifier:len; 143, argument_list; 144, string_content:electron_shells; 145, comparison_operator:sh['angular_momentum'] != am; 146, block; 147, comparison_operator:newsh['function_type'] is None; 148, block; 149, assignment; 150, assignment; 151, boolean_operator; 152, block; 153, assignment; 154, identifier:g; 155, call; 156, block; 157, augmented_assignment; 158, identifier:newshells; 159, identifier:append; 160, identifier:newsh; 161, identifier:sh; 162, string; 163, attribute; 164, argument_list; 165, string; 166, identifier:am; 167, string; 168, list; 169, string; 170, list; 171, string; 172, string; 173, string; 174, None; 175, subscript; 176, identifier:am; 177, continue_statement; 178, attribute; 179, argument_list; 180, subscript; 181, subscript; 182, identifier:am; 183, continue_statement; 184, subscript; 185, None; 186, expression_statement; 187, identifier:ft1; 188, subscript; 189, identifier:ft2; 190, subscript; 191, comparison_operator:ft1 not in ft2; 192, comparison_operator:ft2 not in ft1; 193, raise_statement; 194, identifier:ngen; 195, call; 196, identifier:range; 197, argument_list; 198, expression_statement; 199, expression_statement; 200, expression_statement; 201, expression_statement; 202, identifier:cur_prim; 203, call; 204, string_content:angular_momentum; 205, identifier:all_am; 206, identifier:append; 207, subscript; 208, string_content:angular_momentum; 209, string_content:exponents; 210, string_content:coefficients; 211, string_content:region; 212, string_content:function_type; 213, identifier:sh; 214, string; 215, subscript; 216, identifier:extend; 217, subscript; 218, identifier:newsh; 219, string; 220, identifier:sh; 221, string; 222, identifier:newsh; 223, string; 224, assignment; 225, identifier:newsh; 226, string; 227, identifier:sh; 228, string; 229, identifier:ft1; 230, identifier:ft2; 231, identifier:ft2; 232, identifier:ft1; 233, call; 234, identifier:len; 235, argument_list; 236, identifier:ngen; 237, assignment; 238, call; 239, call; 240, call; 241, identifier:len; 242, argument_list; 243, identifier:sh; 244, string; 245, string_content:angular_momentum; 246, identifier:newsh; 247, string; 248, identifier:sh; 249, string; 250, string_content:exponents; 251, string_content:angular_momentum; 252, string_content:function_type; 253, subscript; 254, subscript; 255, string_content:function_type; 256, string_content:function_type; 257, identifier:RuntimeError; 258, argument_list; 259, subscript; 260, identifier:coef; 261, binary_operator:[zero] * cur_prim; 262, attribute; 263, argument_list; 264, attribute; 265, argument_list; 266, attribute; 267, argument_list; 268, subscript; 269, string_content:angular_momentum; 270, string_content:exponents; 271, string_content:exponents; 272, identifier:newsh; 273, string; 274, identifier:sh; 275, string; 276, string:"Cannot make general contraction of different function types"; 277, identifier:sh; 278, string; 279, list; 280, identifier:cur_prim; 281, identifier:coef; 282, identifier:extend; 283, subscript; 284, identifier:coef; 285, identifier:extend; 286, binary_operator:[zero] * (nprim - len(coef)); 287, subscript; 288, identifier:append; 289, identifier:coef; 290, identifier:sh; 291, string; 292, string_content:function_type; 293, string_content:function_type; 294, string_content:coefficients; 295, identifier:zero; 296, subscript; 297, identifier:g; 298, list; 299, parenthesized_expression; 300, identifier:newsh; 301, string; 302, string_content:exponents; 303, identifier:sh; 304, string; 305, identifier:zero; 306, binary_operator:nprim - len(coef); 307, string_content:coefficients; 308, string_content:coefficients; 309, identifier:nprim; 310, call; 311, identifier:len; 312, argument_list; 313, identifier:coef
code: def make_general(basis, use_copy=True):
      """
      Makes one large general contraction for each angular momentum
  
      If use_copy is True, the input basis set is not modified.
  
      The output of this function is not pretty. If you want to make it nicer,
      use sort_basis afterwards.
      """
  
      zero = '0.00000000'
  
      basis = uncontract_spdf(basis, 0, use_copy)
  
      for k, el in basis['elements'].items():
          if not 'electron_shells' in el:
              continue
  
          # See what we have
          all_am = []
          for sh in el['electron_shells']:
              if not sh['angular_momentum'] in all_am:
                  all_am.append(sh['angular_momentum'])
  
          all_am = sorted(all_am)
  
          newshells = []
          for am in all_am:
              newsh = {
                  'angular_momentum': am,
                  'exponents': [],
                  'coefficients': [],
                  'region': '',
                  'function_type': None,
              }
  
              # Do exponents first
              for sh in el['electron_shells']:
                  if sh['angular_momentum'] != am:
                      continue
                  newsh['exponents'].extend(sh['exponents'])
  
              # Number of primitives in the new shell
              nprim = len(newsh['exponents'])
  
              cur_prim = 0
              for sh in el['electron_shells']:
                  if sh['angular_momentum'] != am:
                      continue
  
                  if newsh['function_type'] is None:
                      newsh['function_type'] = sh['function_type']
  
                  # Make sure the shells we are merging have the same function types
                  ft1 = newsh['function_type']
                  ft2 = sh['function_type']
  
                  # Check if one function type is the subset of another
                  # (should handle gto/gto_spherical, etc)
                  if ft1 not in ft2 and ft2 not in ft1:
                      raise RuntimeError("Cannot make general contraction of different function types")
  
                  ngen = len(sh['coefficients'])
  
                  for g in range(ngen):
                      coef = [zero] * cur_prim
                      coef.extend(sh['coefficients'][g])
                      coef.extend([zero] * (nprim - len(coef)))
                      newsh['coefficients'].append(coef)
  
                  cur_prim += len(sh['exponents'])
  
              newshells.append(newsh)
  
          el['electron_shells'] = newshells
  
      return basis