Create a Dataframe with the contents of the ODF file

    For more information on the ODF format see:
    http://software.broadinstitute.org/cancer/software/genepattern/file-formats-guide

    :odf_obj: The ODF file. Accepts a file-like object, a file path, a URL to the file
              or a string containing the raw data.

def ODF(odf_obj):
    """
    Create a Dataframe with the contents of the ODF file

    For more information on the ODF format see:
    http://software.broadinstitute.org/cancer/software/genepattern/file-formats-guide

    :odf_obj: The ODF file. Accepts a file-like object, a file path, a URL to the file
              or a string containing the raw data.
    """

    # Handle all the various initialization types and get an IO object
    odf_io = _obtain_io(odf_obj)

    # Read the file as an array of lines
    raw_lines = odf_io.readlines()

    # Convert byte strings to unicode strings
    raw_lines = _bytes_to_str(raw_lines)

    try:
        # Read the header count
        header_count = _extract_header_number(raw_lines)

        # Read the header dict
        headers = _parse_header(raw_lines)

        # Read the model
        model = _extract_model(headers)

        # Read the column names, if available
        column_names = _extract_column_names(headers)

        # Assemble the data
        data_lines = _join_data_lines(raw_lines, header_count)

        # Put together new IO
        odf_string_io = io.StringIO(data_lines)

        # Load the ODF file into a DataFrame
        df = pd.read_csv(odf_string_io, sep='\t', header=None, names=column_names, skip_blank_lines=True)

        # Apply backwards compatible methods
        _apply_backwards_compatibility(df)

        # Apply ODF-specific properties
        _apply_odf_properties(df, headers, model)

        # Return the Dataframe
        return df

    # Catch any errors related to parsing the ODF file
    except Exception:
        raise TypeError('Error parsing ODF file')