# Path: mirtop/gff/body.py
# def paste_columns(line, sep=" "):
#     """
#     Create GFF/GTF line from read_gff_line
#     """
#     cols = line.columns
#     attr = line.attributes
#     attr_paste = "; ".join(
#         "%s%s%s" % (a, sep, attr[a]) for a in attr)
#     return "\t".join([cols['chrom'], cols['source'], cols['type'],
#                       cols['start'], cols['end'], cols['score'],
#                       cols['strand'], cols['ext'], attr_paste])
# 
# def guess_format(line):
#     return "=" if line.find("Name=") > -1 else " "
# 
# Path: mirtop/gff/classgff.py
# class feature:
#     """"Class with alignment information."""
# 
#     def __init__(self, line, sep="="):
#         # if isinstance(line, basestring) # str in python 3
#         if isinstance(line, dict):
#             line = self.create_line(line, sep)
#         self.line = line
#         self.attributes = {}
#         self.columns = {}
#         self.read_gff_line()
#         self.reserved_attributes = gff_versions.ATTRv['1.1']
# 
#     def guess_format(self):
#         return "=" if self.line.find("Name=") > -1 else " "
# 
#     def create_line(self, fields, sep):
#         """
#         Create GFF/GTF line from dictionary with fields
#         """
#         # TODO: need unit test. Check all exists.
#         fields["attrb"] = ("Read {seq_name}; UID {idseq}; Name {name};"
#                            "Parent {parent}; "
#                            "Variant {variant}; Cigar {cigar};"
#                            "Expression {counts}; "
#                            "Filter {filter}; Hits {hits};").format(**fields)
# 
#         line = ("{chrom}\t{database}\t{source}\t{start}\t{end}"
#                 "\t{score}\t{strand}\t.\t{attrb}").format(**fields)
#         return line
# 
#     def paste_columns(self, sep=None):
#         """
#         Create GFF/GTF line from read_gff_line
#         """
#         sep = self.guess_format()
#         attributes = "%s;" % "; ".join(
#             "%s%s%s" % (a, sep, self.attributes[a]) for a in self.attributes)
#         return "\t".join([self.columns['chrom'], self.columns['source'],
#                           self.columns['type'],
#                           self.columns['start'], self.columns['end'],
#                           self.columns['score'],
#                           self.columns['strand'], self.columns['ext'],
#                           attributes])
# 
#     def read_attributes(self, gff_attrb, sep=" "):
#         """
#         Read GFF/GTF attributes and return dictionary with fields
#         """
#         sep = self.guess_format()
#         gff_dict = OrderedDict()
#         for gff_item in gff_attrb.split(";"):
#             item_pair = gff_item.strip().split(sep)
#             if len(item_pair) > 1:
#                 gff_dict[item_pair[0].strip()] = item_pair[1].strip()
#         self.attributes = gff_dict
# 
#     def read_gff_line(self):
#         """
#         Read GFF/GTF line and return dictionary with fields
#         """
#         line = self.line
#         if line.startswith("#"):
#             return line
#         cols = line.strip().split("\t")
#         if len(cols) != 9:
#             raise ValueError("Line has less than 9 elements: %s" % line)
#         self.read_attributes(cols[8])
#         fields = {'chrom': cols[0],
#                   'source': cols[1],
#                   'type': cols[2],
#                   'start': cols[3],
#                   'end': cols[4],
#                   'score': cols[5],
#                   'strand': cols[6],
#                   'ext': cols[7]}
#         self.columns = fields


from collections import defaultdict
from mirtop.gff.body import paste_columns, guess_format
from mirtop.gff.classgff import feature
import mirtop.libs.logger as mylog
                    logger.debug("MERGE::SAMPLES::counts %s" % [hit[3], hit[2]])
                    formatted_counts = _format_samples_counts(hit[3], hit[2])
                    logger.debug("MERGE::SAMPLES::fixed %s" % formatted_counts)
                    for sample in formatted_counts:
                        all_data[idu][sample] = formatted_counts[sample] # get the expression of the sample from line
                    all_lines[idu] = hit[4] # get the line
    for idu in all_data:
        line = all_lines[idu]
        expression = _convert_to_string(all_data[idu], samples)
        if _start(line) not in merged_lines[_chrom(line)]:
            merged_lines[_chrom(line)][_start(line)] = []
        merged_lines[_chrom(line)][_start(line)].append([idu, "", "", "",
                                                             _fix(line, expression)])
    return merged_lines


def _format_samples_counts(samples, expression):
    """Return a dictionary of samples counts"""
    if isinstance(samples, list):
        if len(samples) != len(expression):
            raise ValueError("samples %s has different length than expression %s" % (samples,
                                                                                     expression))
    else:
        samples = [samples]
        expression = [expression]
    return dict(zip(samples, expression))


def _fix(line, expression):
    # Need to fix Read attribute since not usefull when multiple sample in a line.

# Path: mirtop/gff/body.py
# def paste_columns(line, sep=" "):
#     """
#     Create GFF/GTF line from read_gff_line
#     """
#     cols = line.columns
#     attr = line.attributes
#     attr_paste = "; ".join(
#         "%s%s%s" % (a, sep, attr[a]) for a in attr)
#     return "\t".join([cols['chrom'], cols['source'], cols['type'],
#                       cols['start'], cols['end'], cols['score'],
#                       cols['strand'], cols['ext'], attr_paste])
# 
# def guess_format(line):
#     return "=" if line.find("Name=") > -1 else " "
# 
# Path: mirtop/gff/classgff.py
# class feature:
#     """"Class with alignment information."""
# 
#     def __init__(self, line, sep="="):
#         # if isinstance(line, basestring) # str in python 3
#         if isinstance(line, dict):
#             line = self.create_line(line, sep)
#         self.line = line
#         self.attributes = {}
#         self.columns = {}
#         self.read_gff_line()
#         self.reserved_attributes = gff_versions.ATTRv['1.1']
# 
#     def guess_format(self):
#         return "=" if self.line.find("Name=") > -1 else " "
# 
#     def create_line(self, fields, sep):
#         """
#         Create GFF/GTF line from dictionary with fields
#         """
#         # TODO: need unit test. Check all exists.
#         fields["attrb"] = ("Read {seq_name}; UID {idseq}; Name {name};"
#                            "Parent {parent}; "
#                            "Variant {variant}; Cigar {cigar};"
#                            "Expression {counts}; "
#                            "Filter {filter}; Hits {hits};").format(**fields)
# 
#         line = ("{chrom}\t{database}\t{source}\t{start}\t{end}"
#                 "\t{score}\t{strand}\t.\t{attrb}").format(**fields)
#         return line
# 
#     def paste_columns(self, sep=None):
#         """
#         Create GFF/GTF line from read_gff_line
#         """
#         sep = self.guess_format()
#         attributes = "%s;" % "; ".join(
#             "%s%s%s" % (a, sep, self.attributes[a]) for a in self.attributes)
#         return "\t".join([self.columns['chrom'], self.columns['source'],
#                           self.columns['type'],
#                           self.columns['start'], self.columns['end'],
#                           self.columns['score'],
#                           self.columns['strand'], self.columns['ext'],
#                           attributes])
# 
#     def read_attributes(self, gff_attrb, sep=" "):
#         """
#         Read GFF/GTF attributes and return dictionary with fields
#         """
#         sep = self.guess_format()
#         gff_dict = OrderedDict()
#         for gff_item in gff_attrb.split(";"):
#             item_pair = gff_item.strip().split(sep)
#             if len(item_pair) > 1:
#                 gff_dict[item_pair[0].strip()] = item_pair[1].strip()
#         self.attributes = gff_dict
# 
#     def read_gff_line(self):
#         """
#         Read GFF/GTF line and return dictionary with fields
#         """
#         line = self.line
#         if line.startswith("#"):
#             return line
#         cols = line.strip().split("\t")
#         if len(cols) != 9:
#             raise ValueError("Line has less than 9 elements: %s" % line)
#         self.read_attributes(cols[8])
#         fields = {'chrom': cols[0],
#                   'source': cols[1],
#                   'type': cols[2],
#                   'start': cols[3],
#                   'end': cols[4],
#                   'score': cols[5],
#                   'strand': cols[6],
#                   'ext': cols[7]}
#         self.columns = fields


# Path: mirtop/gff/merge.py
from collections import defaultdict
from mirtop.gff.body import paste_columns, guess_format
from mirtop.gff.classgff import feature
import mirtop.libs.logger as mylog

                    logger.debug("MERGE::SAMPLES::counts %s" % [hit[3], hit[2]])
                    formatted_counts = _format_samples_counts(hit[3], hit[2])
                    logger.debug("MERGE::SAMPLES::fixed %s" % formatted_counts)
                    for sample in formatted_counts:
                        all_data[idu][sample] = formatted_counts[sample] # get the expression of the sample from line
                    all_lines[idu] = hit[4] # get the line
    for idu in all_data:
        line = all_lines[idu]
        expression = _convert_to_string(all_data[idu], samples)
        if _start(line) not in merged_lines[_chrom(line)]:
            merged_lines[_chrom(line)][_start(line)] = []
        merged_lines[_chrom(line)][_start(line)].append([idu, "", "", "",
                                                             _fix(line, expression)])
    return merged_lines


def _format_samples_counts(samples, expression):
    """Return a dictionary of samples counts"""
    if isinstance(samples, list):
        if len(samples) != len(expression):
            raise ValueError("samples %s has different length than expression %s" % (samples,
                                                                                     expression))
    else:
        samples = [samples]
        expression = [expression]
    return dict(zip(samples, expression))


def _fix(line, expression):
    # Need to fix Read attribute since not usefull when multiple sample in a line.

    gff = feature(line)