def compare_h5_files(first_file, second_file, node_names=None, detailed_comparison=True, exact=True, rtol=<NUM_LIT>, atol=<NUM_LIT>, chunk_size=<NUM_LIT>):
if node_names and not isinstance(node_names, (list, tuple)):<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>checks_passed = True<EOL>error_msg = "<STR_LIT>"<EOL>with tb.open_file(first_file, '<STR_LIT:r>') as first_h5_file:<EOL><INDENT>with tb.open_file(second_file, '<STR_LIT:r>') as second_h5_file:<EOL><INDENT>def walk_nodes(f, n, g="<STR_LIT:/>"):<EOL><INDENT>for item in f.get_node(f.root, g):<EOL><INDENT>if isinstance(item, tb.group.Group):<EOL><INDENT>walk_nodes(f=f, n=n, g=item._v_pathname)<EOL><DEDENT>else:<EOL><INDENT>n.append(item._v_pathname)<EOL><DEDENT><DEDENT><DEDENT>fist_file_nodes = []<EOL>walk_nodes(f=first_h5_file, n=fist_file_nodes)  <EOL>second_file_nodes = []<EOL>walk_nodes(f=second_h5_file, n=second_file_nodes)  <EOL>if node_names is None:<EOL><INDENT>additional_first_file_nodes = set(fist_file_nodes) - set(second_file_nodes)<EOL>additional_second_file_nodes = set(second_file_nodes) - set(fist_file_nodes)<EOL>if additional_first_file_nodes:<EOL><INDENT>checks_passed = False<EOL>if detailed_comparison:<EOL><INDENT>error_msg += '<STR_LIT>' % (first_file, '<STR_LIT:U+002CU+0020>'.join(additional_first_file_nodes))<EOL><DEDENT><DEDENT>if additional_second_file_nodes:<EOL><INDENT>checks_passed = False<EOL>if detailed_comparison:<EOL><INDENT>error_msg += '<STR_LIT>' % (second_file, '<STR_LIT:U+002CU+0020>'.join(additional_second_file_nodes))<EOL><DEDENT><DEDENT>common_nodes = set(fist_file_nodes) & set(second_file_nodes)<EOL><DEDENT>else:<EOL><INDENT>node_names = [(("<STR_LIT:/>" + name) if (name and name[:<NUM_LIT:1>] != "<STR_LIT:/>") else name) for name in node_names]<EOL>missing_first_file_nodes = set(node_names) - set(fist_file_nodes)<EOL>if missing_first_file_nodes:<EOL><INDENT>checks_passed = False<EOL>if detailed_comparison:<EOL><INDENT>error_msg += '<STR_LIT>' % (first_file, '<STR_LIT:U+002CU+0020>'.join(missing_first_file_nodes))<EOL><DEDENT><DEDENT>missing_second_file_nodes = set(node_names) - set(second_file_nodes)<EOL>if missing_second_file_nodes:<EOL><INDENT>checks_passed = False<EOL>if detailed_comparison:<EOL><INDENT>error_msg += '<STR_LIT>' % (second_file, '<STR_LIT:U+002CU+0020>'.join(missing_second_file_nodes))<EOL><DEDENT><DEDENT>common_nodes = (set(fist_file_nodes) & set(second_file_nodes)) & set(node_names)<EOL><DEDENT>for node_name in common_nodes:  <EOL><INDENT>nrows = first_h5_file.get_node(first_h5_file.root, node_name).nrows<EOL>index_start = <NUM_LIT:0><EOL>while index_start < nrows:<EOL><INDENT>read_nrows = max(<NUM_LIT:1>, int(chunk_size / np.prod(first_h5_file.get_node(first_h5_file.root, node_name).shape[<NUM_LIT:1>:])))<EOL>index_stop = index_start + read_nrows<EOL>first_file_data = first_h5_file.get_node(first_h5_file.root, node_name).read(index_start, index_stop)<EOL>second_file_data = second_h5_file.get_node(second_h5_file.root, node_name).read(index_start, index_stop)<EOL>if exact:<EOL><INDENT>if not nan_equal(first_array=first_file_data, second_array=second_file_data):<EOL><INDENT>checks_passed = False<EOL>if detailed_comparison:<EOL><INDENT>error_msg += ('<STR_LIT>' % node_name) + get_array_differences(first_array=first_file_data, second_array=second_file_data, exact=True)<EOL><DEDENT>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if not nan_close(first_array=first_file_data, second_array=second_file_data, rtol=rtol, atol=atol, equal_nan=True):<EOL><INDENT>checks_passed = False<EOL>if detailed_comparison:<EOL><INDENT>error_msg += ('<STR_LIT>' % node_name) + get_array_differences(first_array=first_file_data, second_array=second_file_data, exact=False, rtol=rtol, atol=atol, equal_nan=True)<EOL><DEDENT>break<EOL><DEDENT><DEDENT>index_start += read_nrows<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if checks_passed:<EOL><INDENT>error_msg = '<STR_LIT>' % (first_file, second_file, error_msg)<EOL><DEDENT>else:<EOL><INDENT>error_msg = '<STR_LIT>' % (first_file, second_file, error_msg)<EOL><DEDENT>return checks_passed, error_msg<EOL>
Takes two hdf5 files and check for equality of all nodes.
    Returns true if the node data is equal and the number of nodes is the number of expected nodes.
    It also returns a error string containing the names of the nodes that are not equal.

    Parameters
    ----------
    first_file : string
        Path to the first file.
    second_file : string
        Path to the second file.
    node_names : list, tuple
        Iterable of node names that are required to exist and will be compared.
        If None, compare all existing nodes and fail if nodes are not existing.
    detailed_comparison : boolean
        Print reason why the comparison failed
    exact : boolean
        True if the results have to match exactly. E.g. False for fit results.
    rtol, atol: number
        From numpy.allclose:
        rtol : float
            The relative tolerance parameter (see Notes).
        atol : float
            The absolute tolerance parameter (see Notes).

    Returns
    -------
    (bool, string)