-----
    Brief
    -----
    Universal function for reading the header of .txt, .h5 and .edf files generated by OpenSignals.

    -----------
    Description
    -----------
    Each file generated by the OpenSignals software (available at https://www.biosignalsplux.com/en/software) owns a set
    of metadata that allows the proper identification and characterization of each acquisition, by the identification of
    the mac address of the devices, date of acquisition, duration, number of samples, type of the devices and firmware
    version.

    This function allows to easily access all of this information using only one line of code and outputs a dictionary
    to easily identify each field of the header of file.

    ----------
    Parameters
    ----------
    file : file path
        File path.

    Returns
    -------
    out : dict
        Header data read from the input file as dictionary with keys:
            [mac address]: The key is a string with the mac address of the device;
            sensor: Sensor(s) used in the acquisition;
            device name: String with the mac address identifying the device used in the acquisition process;
            sync interval: Time interval (in seconds) at which a digital signal is sent by a
                “pacemaker” thread to a single device (used when the sync mode in on OpenSignals for synchronized data
                acquisition using multiple devices);
            time: Time of the acquisition;
            comments: Comments inserted in the OpenSignals software after the acquisition;
            device connection: Used connection to the device while using it;
            channels: Used channels;
            keywords: Keywords inserted in the OpenSignals software after the acquisition;
            digital IO: Digital channels available in each device (0 is the Input and 1 is the Output);
            firmware version: Firmware version of the device;
            device: Type of device used during the acquisition;
            sampling rate: Sampling rate set prior to the acquisition;
            resolution: Resolution set prior to the acquisition;
            date: Date of the acquisition;
            column labels: Labels of each set of data (e.g. channel 1).

def read_header(file):
    """
    -----
    Brief
    -----
    Universal function for reading the header of .txt, .h5 and .edf files generated by OpenSignals.

    -----------
    Description
    -----------
    Each file generated by the OpenSignals software (available at https://www.biosignalsplux.com/en/software) owns a set
    of metadata that allows the proper identification and characterization of each acquisition, by the identification of
    the mac address of the devices, date of acquisition, duration, number of samples, type of the devices and firmware
    version.

    This function allows to easily access all of this information using only one line of code and outputs a dictionary
    to easily identify each field of the header of file.

    ----------
    Parameters
    ----------
    file : file path
        File path.

    Returns
    -------
    out : dict
        Header data read from the input file as dictionary with keys:
            [mac address]: The key is a string with the mac address of the device;
            sensor: Sensor(s) used in the acquisition;
            device name: String with the mac address identifying the device used in the acquisition process;
            sync interval: Time interval (in seconds) at which a digital signal is sent by a
                “pacemaker” thread to a single device (used when the sync mode in on OpenSignals for synchronized data
                acquisition using multiple devices);
            time: Time of the acquisition;
            comments: Comments inserted in the OpenSignals software after the acquisition;
            device connection: Used connection to the device while using it;
            channels: Used channels;
            keywords: Keywords inserted in the OpenSignals software after the acquisition;
            digital IO: Digital channels available in each device (0 is the Input and 1 is the Output);
            firmware version: Firmware version of the device;
            device: Type of device used during the acquisition;
            sampling rate: Sampling rate set prior to the acquisition;
            resolution: Resolution set prior to the acquisition;
            date: Date of the acquisition;
            column labels: Labels of each set of data (e.g. channel 1).

    """

    # =============================================================================================
    # ============================== Identification of File Type ==================================
    # =============================================================================================

    file_type = _file_type(file)

    # =============================================================================================
    # ========================= Read Header accordingly to file type ==============================
    # =============================================================================================

    if file_type in ["txt", "plain", "bat"]:
        file_temp = open(file, "r")
        header = file_temp.readlines()[1]
        file_temp.close()

        # -------------------------- Conversion to dictionary. ------------------------------------
        header = ast.literal_eval(header.split("# ")[1].split("\n")[0])

        # -------------------------- Standardization of Header ------------------------------------
        macs = header.keys()
        col_nbr = 0
        for mac in macs:
            # ------------ Removal of "special", "sensor", "mode" and "position" keys -------------
            del header[mac]["special"]
            #del header[mac]["sensor"]
            del header[mac]["position"]
            del header[mac]["mode"]

            # ---------------- Combination of the information in "label" and "column" -------------
            column_labels = {}
            for chn_nbr, chn in enumerate(header[mac]["channels"]):
                chn_label = header[mac]["label"][chn_nbr]
                column_labels[chn] = col_nbr + numpy.where(numpy.array(header[mac]["column"]) ==
                                                           chn_label)[0][0]
            header[mac]["column labels"] = column_labels

            col_nbr += len(header[mac]["column"])
            del header[mac]["column"]
            del header[mac]["label"]

    elif file_type in ["h5", "x-hdf", "a"]:
        file_temp = h5py.File(file)
        macs = file_temp.keys()

        header = {}
        for mac in macs:
            header[mac] = dict(file_temp.get(mac).attrs.items())
            header[mac]["sensor"] = []
            # --------- Removal of "duration", "keywords", "mode", "nsamples" ... keys ------------
            for key in ["duration", "mode", "keywords", "nsamples", "forcePlatform values",
                        "macaddress"]:
                if key in header[mac].keys():
                    del header[mac][key]
                    # del header[mac]["duration"]
                    # del header[mac]["mode"]
                    # del header[mac]["keywords"]
                    # del header[mac]["nsamples"]
                    # del header[mac]["forcePlatform values"]
                    # del header[mac]["macaddress"]

            # -------------- Inclusion of a field used in .txt files (Convergence) ----------------
            column_labels = {}
            for chn in header[mac]["channels"]:
                chn_label = "channel_" + str(chn)
                column_labels[chn] = chn_label
                header[mac]["sensor"].append(dict(file_temp.get(mac).get("raw").get("channel_" + str(chn)).attrs.items())["sensor"])
            header[mac]["column labels"] = column_labels

        file_temp.close()

    # elif file_type in ["edf", "octet-stream"]:
    #
    #     # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    #     # %%%%%%%%%%%% Code taken from convertEDF function of OpenSignals fileHandler %%%%%%%%%%%%%%
    #     # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    #
    #     file_temp = pyedflib.EdfReader(file)
    #     # nbrSamples = file_temp.getNSamples()[0]
    #     nbr_signals = file_temp.signals_in_file
    #     file_header = file_temp.getHeader()
    #     start_date = file_header["startdate"]
    #     file_header["equipment"] += "']"
    #     equipment = ast.literal_eval(file_header['equipment'])
    #     equipment = [n.replace(" ", "_") for n in equipment]
    #     headers = file_temp.getSignalHeaders()
    #     header = {}
    #     mac_address_list = []
    #
    #     # ---------------------------------- Mac Address List --------------------------------------
    #     for signal_nbr in numpy.arange(nbr_signals):
    #         config = headers[signal_nbr]
    #         mac_address = config["transducer"].split(",")[0]
    #
    #         if mac_address not in header.keys():
    #             mac_address_list.append(mac_address)
    #             header[mac_address] = {}
    #             header[mac_address]["device name"] = mac_address
    #             header[mac_address]["sync interval"] = 2
    #             header[mac_address]["time"] = start_date.strftime('%H:%M:%S.%f')[:-3]
    #             header[mac_address]["comments"] = ""
    #             header[mac_address]["device connection"] = ""
    #             header[mac_address]["channels"] = []
    #             header[mac_address]["date"] = start_date.strftime('%Y-%m-%d')
    #             header[mac_address]["digital IO"] = []
    #
    #             if "," in config['transducer']:
    #                 header[mac_address]["firmware version"] = int(config['transducer'].
    #                                                               split(",")[1])
    #             else:
    #                 header[mac_address]["firmware version"] = ""
    #
    #             header[mac_address]["device"] = equipment[len(mac_address_list) - 1]
    #             header[mac_address]["sampling rate"] = int(config['sample_rate'])
    #             header[mac_address]["resolution"] = []
    #             header[mac_address]["column labels"] = {}
    #         if "," in config['prefilter']:
    #             header[mac_address]["channels"].append(int(config['prefilter'].split(",")[0]))
    #             header[mac_address]["resolution"].append(int(config['prefilter'].split(",")[1]))

    else:
        raise RuntimeError("The type of the input file does not correspond to the predefined "
                           "formats of OpenSignals")

    return header