<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def header_fields_from_table(spec_table, keys, dtype_map):
 """Convert the specification table to a standardized format. The specification table is assumed to be in `reST grid table format <http://docutils.sourceforge.net/docs/user/rst/quickref.html#tables>`_. It must have the following 5 columns: 1. ID : an arbitrary unique identifier, e.g., a number. 2. Byte range : Bytes in the file covered by this field, given as number range (e.g. ``15-24``). The byte values start at 1 (not 0), and the upper value of the range is included. 3. Data type : Field values are stored in this format. For multiple entries, a shape can be specified immediately after the type specifier, e.g., ``Float32(4)`` or ``Int32(2,2)``. It is also possible to give an incomplete shape, e.g., ``Int32(2)`` with a 24-byte field. In this case, the shape is completed to ``(3, 2)`` automatically. By default, the one-dimensional shape is determined from the data type and the byte range. The data type must map to a NumPy data type (``dtype_map``). 4. Name : The name of the field as used later (in lowercase) for identification. 5. Description : An explanation of the field. The converted specification is a tuple of dictionaries, each corresponding to one (multi-)row (=field) of the original table. Each field has key-value pairs for the following keys: |Name |Data type|Description | +==============+=========+==========================================+ |'name' |string |Name of the element | |'offset' |int |Offset of the current element in bytes | |'size' |int |Size of the current element in bytes | |'dtype' |type |Data type of the current element as | | | |defined by Numpy | |'description' |string |Description of the element (optional) | |'dshape' |tuple |For multi-elements: number of elements per| | | |dimension. Optional for single elements. | Parameters spec_table : str Specification given as a string containing a definition table. keys : dict Dictionary with the following entries for the column headers in the specification table: - ``'id'`` - ``'byte_range'`` - ``'dtype'`` - ``'name'`` - ``'description'`` dtype_map : dict Mapping from the data type specifiers in the specification table to NumPy data types. Returns ------- standardized_fields : tuple of dicts The standardized fields according to the above table, one for each (multi-)row. """

    field_list = _fields_from_table(spec_table, id_key=keys['id'])

    # Parse the fields and represent them in a unfied way
    conv_list = []
    for field in field_list:
        new_field = {}

        # Name and description: lowercase name, copy description
        new_field['name'] = field[keys['name']].lower()
        new_field['description'] = field[keys['description']]

        # Get byte range and set start
        byte_range = field[keys['byte_range']].split('-')
        offset_bytes = int(byte_range[0]) - 1
        end_bytes = int(byte_range[-1]) - 1
        size_bytes = end_bytes - offset_bytes + 1
        new_field['offset'] = offset_bytes
        new_field['size'] = size_bytes

        # Data type: transform to Numpy format and get shape
        dtype_shape = field[keys['dtype']].split('(')
        dtype = dtype_map[dtype_shape[0]]
        new_field['dtype'] = dtype

        if len(dtype_shape) == 2:
            # Shape was given in data type specification

            # Re-attach left parenthesis that was removed in the split
            dshape = np.atleast_1d(eval('(' + dtype_shape[-1]))
            size_bytes_from_shape = np.prod(dshape) * dtype.itemsize
            if size_bytes_from_shape >= size_bytes:
                raise ValueError(
                    "entry '{}': field size {} from shape {} and "
                    "dtype.itemsize {} larger than field size {} from spec"
                    "".format(field[keys['name']], size_bytes_from_shape,
                              dshape, dtype.itemsize, size_bytes))

            # Try to complete the given shape
            if size_bytes % size_bytes_from_shape:
                raise ValueError(
                    "entry '{}': shape {} cannot be completed consistently "
                    "using field size {} and `dtype.itemsize` {}"
                    "".format(field[keys['name']], dshape, size_bytes,
                              dtype.itemsize))

            dshape = (size_bytes // size_bytes_from_shape,) + tuple(dshape)

        else:
            if size_bytes % dtype.itemsize:
                raise ValueError(
                    "entry '{}': field size {} not a multiple of "
                    "`dtype.itemsize` {}"
                    "".format(field[keys['name']], field[keys['byte_range']],
                              dtype.itemsize, field[keys['dtype']]))
            dshape = (size_bytes // dtype.itemsize,)

        new_field['dshape'] = dshape

        conv_list.append(new_field)

    return tuple(conv_list)