nodes: 0, module; 1, function_definition; 2, function_name:open_mfbpchdataset; 3, parameters; 4, block; 5, identifier:paths; 6, default_parameter; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, dictionary_splat_pattern; 11, expression_statement; 12, import_from_statement; 13, comment:# TODO: Include file locks?; 14, comment:# Check for dask; 15, expression_statement; 16, if_statement; 17, expression_statement; 18, comment:# Add th; 19, if_statement; 20, if_statement; 21, expression_statement; 22, expression_statement; 23, if_statement; 24, comment:# Concatenate over time; 25, expression_statement; 26, expression_statement; 27, expression_statement; 28, expression_statement; 29, expression_statement; 30, expression_statement; 31, return_statement; 32, identifier:concat_dim; 33, string; 34, identifier:compat; 35, string; 36, identifier:preprocess; 37, None; 38, identifier:lock; 39, None; 40, identifier:kwargs; 41, comment:""" Open multiple bpch files as a single dataset.
  
      You must have dask installed for this to work, as this greatly
      simplifies issues relating to multi-file I/O.
  
      Also, please note that this is not a very performant routine. I/O is still
      limited by the fact that we need to manually scan/read through each bpch
      file so that we can figure out what its contents are, since that metadata
      isn't saved anywhere. So this routine will actually sequentially load
      Datasets for each bpch file, then concatenate them along the "time" axis.
      You may wish to simply process each file individually, coerce to NetCDF,
      and then ingest through xarray as normal.
  
      Parameters
      ----------
      paths : list of strs
          Filenames to load; order doesn't matter as they will be
          lexicographically sorted before we read in the data
      concat_dim : str, default='time'
          Dimension to concatenate Datasets over. We default to "time" since this
          is how GEOS-Chem splits output files
      compat : str (optional)
          String indicating how to compare variables of the same name for
          potential conflicts when merging:
  
          - 'broadcast_equals': all values must be equal when variables are
            broadcast against each other to ensure common dimensions.
          - 'equals': all values and dimensions must be the same.
          - 'identical': all values, dimensions and attributes must be the
            same.
          - 'no_conflicts': only values which are not null in both datasets
            must be equal. The returned dataset then contains the combination
            of all non-null values.
      preprocess : callable (optional)
          A pre-processing function to apply to each Dataset prior to
          concatenation
      lock : False, True, or threading.Lock (optional)
          Passed to :py:func:`dask.array.from_array`. By default, xarray
          employs a per-variable lock when reading data from NetCDF files,
          but this model has not yet been extended or implemented for bpch files
          and so this is not actually used. However, it is likely necessary
          before dask's multi-threaded backend can be used
      **kwargs : optional
          Additional arguments to pass to :py:func:`xbpch.open_bpchdataset`.
      
      """; 42, dotted_name; 43, dotted_name; 44, assignment; 45, not_operator; 46, block; 47, assignment; 48, call; 49, block; 50, not_operator; 51, block; 52, assignment; 53, assignment; 54, comparison_operator:preprocess is not None; 55, block; 56, assignment; 57, assignment; 58, assignment; 59, assignment; 60, assignment; 61, assignment; 62, identifier:combined; 63, string_content:time; 64, string_content:no_conflicts; 65, identifier:xarray; 66, identifier:backends; 67, identifier:api; 68, identifier:_MultiFileCloser; 69, identifier:dask; 70, call; 71, identifier:dask; 72, raise_statement; 73, subscript; 74, True; 75, identifier:isinstance; 76, argument_list; 77, expression_statement; 78, identifier:paths; 79, raise_statement; 80, identifier:datasets; 81, list_comprehension; 82, identifier:bpch_objs; 83, list_comprehension; 84, identifier:preprocess; 85, None; 86, expression_statement; 87, identifier:combined; 88, call; 89, attribute; 90, call; 91, attribute; 92, attribute; 93, identifier:ts; 94, call; 95, identifier:fns_str; 96, call; 97, subscript; 98, parenthesized_expression; 99, attribute; 100, argument_list; 101, call; 102, identifier:kwargs; 103, string; 104, identifier:paths; 105, identifier:basestring; 106, assignment; 107, call; 108, call; 109, for_in_clause; 110, attribute; 111, for_in_clause; 112, assignment; 113, attribute; 114, argument_list; 115, identifier:combined; 116, identifier:_file_obj; 117, identifier:_MultiFileCloser; 118, argument_list; 119, identifier:combined; 120, identifier:attrs; 121, subscript; 122, identifier:attrs; 123, identifier:get_timestamp; 124, argument_list; 125, attribute; 126, argument_list; 127, attribute; 128, string; 129, call; 130, identifier:kwargs; 131, identifier:pop; 132, string; 133, False; 134, identifier:ValueError; 135, argument_list; 136, string_content:dask; 137, identifier:paths; 138, call; 139, identifier:IOError; 140, argument_list; 141, identifier:open_bpchdataset; 142, argument_list; 143, identifier:filename; 144, identifier:paths; 145, identifier:ds; 146, identifier:_file_obj; 147, identifier:ds; 148, identifier:datasets; 149, identifier:datasets; 150, list_comprehension; 151, identifier:xr; 152, identifier:auto_combine; 153, identifier:datasets; 154, keyword_argument; 155, keyword_argument; 156, identifier:bpch_objs; 157, identifier:datasets; 158, integer:0; 159, string:" "; 160, identifier:join; 161, identifier:paths; 162, identifier:combined; 163, identifier:attrs; 164, string_content:history; 165, attribute; 166, argument_list; 167, string_content:dask; 168, string:"Reading multiple files without dask is not supported"; 169, identifier:sorted; 170, argument_list; 171, string:"No paths to files were passed into open_mfbpchdataset"; 172, identifier:filename; 173, dictionary_splat; 174, call; 175, for_in_clause; 176, identifier:compat; 177, identifier:compat; 178, identifier:concat_dim; 179, identifier:concat_dim; 180, string:"{}: Processed/loaded by xbpch-{} from {}"; 181, identifier:format; 182, identifier:ts; 183, identifier:ver; 184, identifier:fns_str; 185, call; 186, identifier:kwargs; 187, identifier:preprocess; 188, argument_list; 189, identifier:ds; 190, identifier:datasets; 191, identifier:glob; 192, argument_list; 193, identifier:ds; 194, identifier:paths
code: def open_mfbpchdataset(paths, concat_dim='time', compat='no_conflicts',
                         preprocess=None, lock=None, **kwargs):
      """ Open multiple bpch files as a single dataset.
  
      You must have dask installed for this to work, as this greatly
      simplifies issues relating to multi-file I/O.
  
      Also, please note that this is not a very performant routine. I/O is still
      limited by the fact that we need to manually scan/read through each bpch
      file so that we can figure out what its contents are, since that metadata
      isn't saved anywhere. So this routine will actually sequentially load
      Datasets for each bpch file, then concatenate them along the "time" axis.
      You may wish to simply process each file individually, coerce to NetCDF,
      and then ingest through xarray as normal.
  
      Parameters
      ----------
      paths : list of strs
          Filenames to load; order doesn't matter as they will be
          lexicographically sorted before we read in the data
      concat_dim : str, default='time'
          Dimension to concatenate Datasets over. We default to "time" since this
          is how GEOS-Chem splits output files
      compat : str (optional)
          String indicating how to compare variables of the same name for
          potential conflicts when merging:
  
          - 'broadcast_equals': all values must be equal when variables are
            broadcast against each other to ensure common dimensions.
          - 'equals': all values and dimensions must be the same.
          - 'identical': all values, dimensions and attributes must be the
            same.
          - 'no_conflicts': only values which are not null in both datasets
            must be equal. The returned dataset then contains the combination
            of all non-null values.
      preprocess : callable (optional)
          A pre-processing function to apply to each Dataset prior to
          concatenation
      lock : False, True, or threading.Lock (optional)
          Passed to :py:func:`dask.array.from_array`. By default, xarray
          employs a per-variable lock when reading data from NetCDF files,
          but this model has not yet been extended or implemented for bpch files
          and so this is not actually used. However, it is likely necessary
          before dask's multi-threaded backend can be used
      **kwargs : optional
          Additional arguments to pass to :py:func:`xbpch.open_bpchdataset`.
      
      """
  
      from xarray.backends.api import _MultiFileCloser
  
      # TODO: Include file locks?
  
      # Check for dask
      dask = kwargs.pop('dask', False)
      if not dask:
          raise ValueError("Reading multiple files without dask is not supported")
      kwargs['dask'] = True
  
      # Add th
  
      if isinstance(paths, basestring):
          paths = sorted(glob(paths))
      if not paths:
          raise IOError("No paths to files were passed into open_mfbpchdataset")
  
      datasets = [open_bpchdataset(filename, **kwargs)
                  for filename in paths]
      bpch_objs = [ds._file_obj for ds in datasets]
  
      if preprocess is not None:
          datasets = [preprocess(ds) for ds in datasets]
  
      # Concatenate over time
      combined = xr.auto_combine(datasets, compat=compat, concat_dim=concat_dim)
  
      combined._file_obj = _MultiFileCloser(bpch_objs)
      combined.attrs = datasets[0].attrs
      ts = get_timestamp()
      fns_str = " ".join(paths)
      combined.attrs['history'] = (
          "{}: Processed/loaded by xbpch-{} from {}"
          .format(ts, ver, fns_str)
      )
  
  
      return combined