nodes: 0, module; 1, function_definition; 2, function_name:get_key; 3, parameters; 4, block; 5, identifier:key; 6, identifier:key_container; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, default_parameter; 11, default_parameter; 12, default_parameter; 13, default_parameter; 14, expression_statement; 15, if_statement; 16, expression_statement; 17, comment:# further filter by other parameters; 18, if_statement; 19, if_statement; 20, if_statement; 21, if_statement; 22, if_statement; 23, if_statement; 24, if_statement; 25, identifier:num_results; 26, integer:1; 27, identifier:best; 28, True; 29, identifier:resolution; 30, None; 31, identifier:calibration; 32, None; 33, identifier:polarization; 34, None; 35, identifier:level; 36, None; 37, identifier:modifiers; 38, None; 39, comment:"""Get the fully-specified key best matching the provided key.
  
      Only the best match is returned if `best` is `True` (default). See
      `get_best_dataset_key` for more information on how this is determined.
  
      The `resolution` and other identifier keywords are provided as a
      convenience to filter by multiple parameters at once without having
      to filter by multiple `key` inputs.
  
      Args:
          key (DatasetID): DatasetID of query parameters to use for
                           searching. Any parameter that is `None`
                           is considered a wild card and any match is
                           accepted.
          key_container (dict or set): Container of DatasetID objects that
                                       uses hashing to quickly access items.
          num_results (int): Number of results to return. Use `0` for all
                             matching results. If `1` then the single matching
                             key is returned instead of a list of length 1.
                             (default: 1)
          best (bool): Sort results to get "best" result first
                       (default: True). See `get_best_dataset_key` for details.
          resolution (float, int, or list): Resolution of the dataset in
                                            dataset units (typically
                                            meters). This can also be a
                                            list of these numbers.
          calibration (str or list): Dataset calibration
                                     (ex.'reflectance'). This can also be a
                                     list of these strings.
          polarization (str or list): Dataset polarization
                                      (ex.'V'). This can also be a
                                      list of these strings.
          level (number or list): Dataset level (ex. 100). This can also be a
                                  list of these numbers.
          modifiers (list): Modifiers applied to the dataset. Unlike
                            resolution and calibration this is the exact
                            desired list of modifiers for one dataset, not
                            a list of possible modifiers.
  
  
      Returns (list or DatasetID): Matching key(s)
  
      Raises: KeyError if no matching results or if more than one result is
              found when `num_results` is `1`.
  
      """; 40, call; 41, comment:# we want this ID to act as a query so we set modifiers to None; 42, comment:# meaning "we don't care how many modifiers it has".; 43, block; 44, elif_clause; 45, elif_clause; 46, assignment; 47, comparison_operator:resolution is not None; 48, block; 49, comparison_operator:polarization is not None; 50, block; 51, comparison_operator:calibration is not None; 52, block; 53, comparison_operator:level is not None; 54, block; 55, comparison_operator:modifiers is not None; 56, block; 57, identifier:best; 58, block; 59, boolean_operator; 60, block; 61, elif_clause; 62, elif_clause; 63, elif_clause; 64, else_clause; 65, identifier:isinstance; 66, argument_list; 67, expression_statement; 68, call; 69, comment:# ID should act as a query (see wl comment above); 70, block; 71, not_operator; 72, block; 73, identifier:res; 74, call; 75, identifier:resolution; 76, None; 77, if_statement; 78, expression_statement; 79, identifier:polarization; 80, None; 81, if_statement; 82, expression_statement; 83, identifier:calibration; 84, None; 85, if_statement; 86, expression_statement; 87, identifier:level; 88, None; 89, if_statement; 90, expression_statement; 91, identifier:modifiers; 92, None; 93, expression_statement; 94, expression_statement; 95, comparison_operator:num_results == 1; 96, not_operator; 97, raise_statement; 98, boolean_operator; 99, block; 100, comparison_operator:num_results == 1; 101, block; 102, comparison_operator:num_results == 0; 103, block; 104, block; 105, identifier:key; 106, attribute; 107, assignment; 108, identifier:isinstance; 109, argument_list; 110, expression_statement; 111, call; 112, raise_statement; 113, identifier:filter_keys_by_dataset_id; 114, argument_list; 115, not_operator; 116, block; 117, assignment; 118, not_operator; 119, block; 120, assignment; 121, not_operator; 122, block; 123, assignment; 124, not_operator; 125, block; 126, assignment; 127, assignment; 128, assignment; 129, identifier:num_results; 130, integer:1; 131, identifier:res; 132, call; 133, comparison_operator:num_results == 1; 134, comparison_operator:len(res) != 1; 135, raise_statement; 136, identifier:num_results; 137, integer:1; 138, return_statement; 139, identifier:num_results; 140, integer:0; 141, return_statement; 142, return_statement; 143, identifier:numbers; 144, identifier:Number; 145, identifier:key; 146, call; 147, identifier:key; 148, tuple; 149, assignment; 150, identifier:isinstance; 151, argument_list; 152, call; 153, identifier:key; 154, identifier:key_container; 155, call; 156, expression_statement; 157, identifier:res; 158, list_comprehension; 159, call; 160, expression_statement; 161, identifier:res; 162, list_comprehension; 163, call; 164, expression_statement; 165, identifier:res; 166, list_comprehension; 167, call; 168, expression_statement; 169, identifier:res; 170, list_comprehension; 171, identifier:res; 172, list_comprehension; 173, identifier:res; 174, call; 175, identifier:KeyError; 176, argument_list; 177, identifier:num_results; 178, integer:1; 179, call; 180, integer:1; 181, call; 182, subscript; 183, identifier:res; 184, subscript; 185, identifier:DatasetID; 186, argument_list; 187, identifier:str; 188, attribute; 189, identifier:key; 190, call; 191, identifier:key; 192, identifier:DatasetID; 193, identifier:ValueError; 194, argument_list; 195, identifier:isinstance; 196, argument_list; 197, assignment; 198, identifier:k; 199, for_in_clause; 200, if_clause; 201, identifier:isinstance; 202, argument_list; 203, assignment; 204, identifier:k; 205, for_in_clause; 206, if_clause; 207, identifier:isinstance; 208, argument_list; 209, assignment; 210, identifier:k; 211, for_in_clause; 212, if_clause; 213, identifier:isinstance; 214, argument_list; 215, assignment; 216, identifier:k; 217, for_in_clause; 218, if_clause; 219, identifier:k; 220, for_in_clause; 221, if_clause; 222, identifier:get_best_dataset_key; 223, argument_list; 224, call; 225, identifier:len; 226, argument_list; 227, identifier:TooManyResults; 228, argument_list; 229, identifier:res; 230, integer:0; 231, identifier:res; 232, slice; 233, keyword_argument; 234, keyword_argument; 235, identifier:six; 236, identifier:text_type; 237, identifier:DatasetID; 238, argument_list; 239, call; 240, identifier:resolution; 241, tuple; 242, identifier:resolution; 243, tuple; 244, identifier:k; 245, identifier:res; 246, boolean_operator; 247, identifier:polarization; 248, tuple; 249, identifier:polarization; 250, tuple; 251, identifier:k; 252, identifier:res; 253, boolean_operator; 254, identifier:calibration; 255, tuple; 256, identifier:calibration; 257, tuple; 258, identifier:k; 259, identifier:res; 260, boolean_operator; 261, identifier:level; 262, tuple; 263, identifier:level; 264, tuple; 265, identifier:k; 266, identifier:res; 267, boolean_operator; 268, identifier:k; 269, identifier:res; 270, boolean_operator; 271, identifier:key; 272, identifier:res; 273, attribute; 274, argument_list; 275, identifier:res; 276, call; 277, identifier:num_results; 278, identifier:wavelength; 279, identifier:key; 280, identifier:modifiers; 281, None; 282, keyword_argument; 283, keyword_argument; 284, attribute; 285, argument_list; 286, identifier:list; 287, identifier:tuple; 288, identifier:resolution; 289, comparison_operator:k.resolution is not None; 290, comparison_operator:k.resolution in resolution; 291, identifier:list; 292, identifier:tuple; 293, identifier:polarization; 294, comparison_operator:k.polarization is not None; 295, comparison_operator:k.polarization in
                 polarization; 296, identifier:list; 297, identifier:tuple; 298, identifier:calibration; 299, comparison_operator:k.calibration is not None; 300, comparison_operator:k.calibration in calibration; 301, identifier:list; 302, identifier:tuple; 303, identifier:level; 304, comparison_operator:k.level is not None; 305, comparison_operator:k.level in level; 306, comparison_operator:k.modifiers is not None; 307, comparison_operator:k.modifiers == modifiers; 308, string:"No dataset matching '{}' found"; 309, identifier:format; 310, call; 311, attribute; 312, argument_list; 313, identifier:name; 314, identifier:key; 315, identifier:modifiers; 316, None; 317, concatenated_string; 318, identifier:format; 319, call; 320, attribute; 321, None; 322, attribute; 323, identifier:resolution; 324, attribute; 325, None; 326, attribute; 327, identifier:polarization; 328, attribute; 329, None; 330, attribute; 331, identifier:calibration; 332, attribute; 333, None; 334, attribute; 335, identifier:level; 336, attribute; 337, None; 338, attribute; 339, identifier:modifiers; 340, identifier:str; 341, argument_list; 342, string:"No unique dataset matching {}"; 343, identifier:format; 344, call; 345, string:"Expected 'DatasetID', str, or number dict key, "; 346, string:"not {}"; 347, identifier:str; 348, argument_list; 349, identifier:k; 350, identifier:resolution; 351, identifier:k; 352, identifier:resolution; 353, identifier:k; 354, identifier:polarization; 355, identifier:k; 356, identifier:polarization; 357, identifier:k; 358, identifier:calibration; 359, identifier:k; 360, identifier:calibration; 361, identifier:k; 362, identifier:level; 363, identifier:k; 364, identifier:level; 365, identifier:k; 366, identifier:modifiers; 367, identifier:k; 368, identifier:modifiers; 369, identifier:key; 370, identifier:str; 371, argument_list; 372, call; 373, identifier:key; 374, identifier:type; 375, argument_list; 376, identifier:key
code: def get_key(key, key_container, num_results=1, best=True,
              resolution=None, calibration=None, polarization=None,
              level=None, modifiers=None):
      """Get the fully-specified key best matching the provided key.
  
      Only the best match is returned if `best` is `True` (default). See
      `get_best_dataset_key` for more information on how this is determined.
  
      The `resolution` and other identifier keywords are provided as a
      convenience to filter by multiple parameters at once without having
      to filter by multiple `key` inputs.
  
      Args:
          key (DatasetID): DatasetID of query parameters to use for
                           searching. Any parameter that is `None`
                           is considered a wild card and any match is
                           accepted.
          key_container (dict or set): Container of DatasetID objects that
                                       uses hashing to quickly access items.
          num_results (int): Number of results to return. Use `0` for all
                             matching results. If `1` then the single matching
                             key is returned instead of a list of length 1.
                             (default: 1)
          best (bool): Sort results to get "best" result first
                       (default: True). See `get_best_dataset_key` for details.
          resolution (float, int, or list): Resolution of the dataset in
                                            dataset units (typically
                                            meters). This can also be a
                                            list of these numbers.
          calibration (str or list): Dataset calibration
                                     (ex.'reflectance'). This can also be a
                                     list of these strings.
          polarization (str or list): Dataset polarization
                                      (ex.'V'). This can also be a
                                      list of these strings.
          level (number or list): Dataset level (ex. 100). This can also be a
                                  list of these numbers.
          modifiers (list): Modifiers applied to the dataset. Unlike
                            resolution and calibration this is the exact
                            desired list of modifiers for one dataset, not
                            a list of possible modifiers.
  
  
      Returns (list or DatasetID): Matching key(s)
  
      Raises: KeyError if no matching results or if more than one result is
              found when `num_results` is `1`.
  
      """
      if isinstance(key, numbers.Number):
          # we want this ID to act as a query so we set modifiers to None
          # meaning "we don't care how many modifiers it has".
          key = DatasetID(wavelength=key, modifiers=None)
      elif isinstance(key, (str, six.text_type)):
          # ID should act as a query (see wl comment above)
          key = DatasetID(name=key, modifiers=None)
      elif not isinstance(key, DatasetID):
          raise ValueError("Expected 'DatasetID', str, or number dict key, "
                           "not {}".format(str(type(key))))
  
      res = filter_keys_by_dataset_id(key, key_container)
  
      # further filter by other parameters
      if resolution is not None:
          if not isinstance(resolution, (list, tuple)):
              resolution = (resolution, )
          res = [k for k in res
                 if k.resolution is not None and k.resolution in resolution]
      if polarization is not None:
          if not isinstance(polarization, (list, tuple)):
              polarization = (polarization, )
          res = [k for k in res
                 if k.polarization is not None and k.polarization in
                 polarization]
      if calibration is not None:
          if not isinstance(calibration, (list, tuple)):
              calibration = (calibration, )
          res = [k for k in res
                 if k.calibration is not None and k.calibration in calibration]
      if level is not None:
          if not isinstance(level, (list, tuple)):
              level = (level, )
          res = [k for k in res
                 if k.level is not None and k.level in level]
      if modifiers is not None:
          res = [k for k in res
                 if k.modifiers is not None and k.modifiers == modifiers]
  
      if best:
          res = get_best_dataset_key(key, res)
  
      if num_results == 1 and not res:
          raise KeyError("No dataset matching '{}' found".format(str(key)))
      elif num_results == 1 and len(res) != 1:
          raise TooManyResults("No unique dataset matching {}".format(str(key)))
      elif num_results == 1:
          return res[0]
      elif num_results == 0:
          return res
      else:
          return res[:num_results]