Commit fd717d77 authored by Tamara Hodgetts's avatar Tamara Hodgetts
Browse files

python samplesheet _check changes

parent ea66eb10
Loading
Loading
Loading
Loading
+60 −45
Original line number Diff line number Diff line
@@ -43,23 +43,26 @@ def check_samplesheet(file_in, file_out, igg_control):
    """
    This function checks that the samplesheet follows the following structure:

    group,replicate,control_group,fastq_1,fastq_2
    WT,1,1,WT_LIB1_REP1_1.fastq.gz,WT_LIB1_REP1_2.fastq.gz
    WT,1,1,WT_LIB2_REP1_1.fastq.gz,WT_LIB2_REP1_2.fastq.gz
    WT,2,1,WT_LIB1_REP2_1.fastq.gz,WT_LIB1_REP2_2.fastq.gz
    KO,1,2,KO_LIB1_REP1_1.fastq.gz,KO_LIB1_REP1_2.fastq.gz
    IGG,1,1,KO_LIB1_REP1_1.fastq.gz,IGG_LIB1_REP1_2.fastq.gz
    IGG,2,2,KO_LIB1_REP1_1.fastq.gz,IGG_LIB1_REP1_2.fastq.gz
    group,replicate,fastq_1,fastq_2,control
    WT,1,WT_LIB1_REP1_1.fastq.gz,WT_LIB1_REP1_2.fastq.gz,IGG_group1
    WT,1,WT_LIB2_REP1_1.fastq.gz,WT_LIB2_REP1_2.fastq.gz,IGG_group1
    WT,2,WT_LIB1_REP2_1.fastq.gz,WT_LIB1_REP2_2.fastq.gz,IGG_group1
    KO,1,KO_LIB1_REP1_1.fastq.gz,KO_LIB1_REP1_2.fastq.gz,IGG_group1
    IGG_group1,1,KO_LIB1_REP1_1.fastq.gz,IGG_LIB1_REP1_2.fastq.gz, 
    IGG_group1,2,KO_LIB1_REP1_1.fastq.gz,IGG_LIB1_REP1_2.fastq.gz, 
    """

    igg_present = False

    num_fastq_list     = []
    sample_names_list  = []
    control_names_list = []
    sample_run_dict = {}
    with open(file_in, "r") as fin:

        ## Check header
        MIN_COLS = 3
        HEADER = ["group", "replicate", "control_group", "fastq_1", "fastq_2"]
        HEADER = ["group", "replicate", "fastq_1", "fastq_2", "control"]
        header = [x.strip('"') for x in fin.readline().strip().split(",")]
        if header[: len(HEADER)] != HEADER:
            print("ERROR: Please check samplesheet header -> {} != {}".format(",".join(header), ",".join(HEADER)))
@@ -69,17 +72,20 @@ def check_samplesheet(file_in, file_out, igg_control):
        for line in fin:
            lspl = [x.strip().strip('"') for x in line.strip().split(",")]

            ## Set control_present to true if the control column is not empty
            if not igg_present:
                if 'igg' in lspl:
                if lspl[4] != "":
                    igg_present = True 

            ## Check valid number of columns per row
            if len(lspl) < len(HEADER):
            if len(lspl) != 5:
                print_error(
                    "Invalid number of columns (minimum = {})!".format(len(HEADER)),
                    "Invalid number of columns (should be {})!".format(len(HEADER)),
                    "Line",
                    line,
                )

            ## Check valid number of populated columns per row
            num_cols = len([x for x in lspl if x])
            if num_cols < MIN_COLS:
                print_error(
@@ -89,13 +95,21 @@ def check_samplesheet(file_in, file_out, igg_control):
                )

            ## Check sample name entries
            sample, replicate, control_group, fastq_1, fastq_2 = lspl[: len(HEADER)]
            sample, replicate, fastq_1, fastq_2, control = lspl[: len(HEADER)]
            if sample:
                if sample.find(" ") != -1:
                    print_error("Group entry contains spaces!", "Line", line)
            else:
                print_error("Group entry has not been specified!", "Line", line)

            if control:
                if control.find(" ") != -1:
                    print_error("Control entry contains spaces!", "Line", line)

            ## Check control sample name is not equal to sample name entry
            if sample == control:
                print_error("Control entry and sample entry must be different!", "Line", line)

            ## Check replicate entry is integer
            if not replicate.isdigit():
                print_error("Replicate id not an integer!", "Line", line)
@@ -112,13 +126,15 @@ def check_samplesheet(file_in, file_out, igg_control):
                            "Line",
                            line,
                        )
            num_fastq = len([fastq for fastq in [fastq_1, fastq_2] if fastq])
            num_fastq_list.append(num_fastq)

            ## Auto-detect paired-end/single-end
            sample_info = []
            if sample and fastq_1 and fastq_2:  ## Paired-end short reads
                sample_info = [sample, str(replicate), control_group, "0", fastq_1, fastq_2]
                sample_info = [sample, str(replicate), control, "0", fastq_1, fastq_2]
            elif sample and fastq_1 and not fastq_2:  ## Single-end short reads
                sample_info = [sample, str(replicate), control_group, "1", fastq_1, fastq_2]
                sample_info = [sample, str(replicate), control, "1", fastq_1, fastq_2]
            else:
                print_error("Invalid combination of columns provided!", "Line", line)
            ## Create sample mapping dictionary = {sample: {replicate : [ single_end, fastq_1, fastq_2 ]}}
@@ -132,6 +148,26 @@ def check_samplesheet(file_in, file_out, igg_control):
                else:
                    sample_run_dict[sample][replicate].append(sample_info)
            
            ## Store unique group names
            if sample not in sample_names_list:
                sample_names_list.append(sample)

            ## Store unique control names
            if control not in control_names_list:
                control_names_list.append(control)

    ## Check data is either paired-end/single-end and not both
    if min(num_fastq_list) != max(num_fastq_list):
        print_error("Mixture of paired-end and single-end reads!")
        sys.exit(1)

    ## Check control group exists
    for ctrl in control_names_list:
        if ctrl != "" and ctrl not in sample_names_list:
            CTRL = ctrl
            print_error("Each control entry must match at least one group entry! Unmatched control entry: {}.".format(CTRL))
            sys.exit(1)

    ## Check igg_control parameter is consistent with input groups
    if (igg_control == 'true' and not igg_present):
        print("ERROR: No 'igg' group was found in " + str(file_in) + " If you are not supplying an IgG control, please specify --igg_control 'false' on command line.")
@@ -141,25 +177,13 @@ def check_samplesheet(file_in, file_out, igg_control):
        print("ERROR: Parameter --igg_control was set to false, but an 'igg' group was found in " + str(file_in) + ".")
        sys.exit(1)

    ## Check control groups have unique ids that are the same as their replicate ids
    control_group_ids = []
    if igg_present:
        for key, data in sample_run_dict["igg"].items():
            for tech_rep in data:
                if tech_rep[2] not in control_group_ids:
                    control_group_ids.append(tech_rep[2])

                if(tech_rep[2] != str(key)):
                    print("ERROR: IgG groups must have a control id equal to the replicate id")
                    sys.exit(1)

    ## Write validated samplesheet with appropriate columns
    if len(sample_run_dict) > 0:
        out_dir = os.path.dirname(file_out)
        make_dir(out_dir)
        with open(file_out, "w") as fout:

            fout.write(",".join(["id", "group", "replicate", "control_group", "single_end", "fastq_1", "fastq_2"]) + "\n")
            fout.write(",".join(["id", "group", "replicate", "control", "single_end", "fastq_1", "fastq_2"]) + "\n")
            for sample in sorted(sample_run_dict.keys()):

                ## Check that replicate ids are in format 1..<NUM_REPS>
@@ -172,15 +196,6 @@ def check_samplesheet(file_in, file_out, igg_control):
                    )
                for replicate in sorted(sample_run_dict[sample].keys()):

                    ## Check control group exists
                    if igg_present:
                        for tech_rep in sample_run_dict[sample][replicate]:
                            if tech_rep[2] not in control_group_ids:
                                print_error(
                                    "Control group does not exist",
                                    tech_rep[2]
                                )

                    ## Check tech reps have same control group id
                    check_group = sample_run_dict[sample][replicate][0][2]
                    for tech_rep in sample_run_dict[sample][replicate]: