diff --git a/docs/questions/split-flongle.md b/docs/questions/split-flongle.md new file mode 100644 index 00000000..91014b4e --- /dev/null +++ b/docs/questions/split-flongle.md @@ -0,0 +1,35 @@ +--- +title: "Splitting a flongle into regions" +alt_titles: + - "Flow cell splitting + - "Flongle splitting" + - "ValueError: channel cannot be below 0 or above flowcell_size" +--- + +The flow cell can be split both vertically and horizontally, with the `split_axis` parameter in the TOML file deciding this. +The axis can be either 0 or 1, with 0 splitting horizontally and 1 splitting vertically. +The default value is 1, so this only needs setting if you wish to split horizontally. + +```text + Vertical (axis=1) Horizontal (axis=0) ++------------+ +------+------+ | +------------+ +------------+ +| 1 2 3 4| | 1 2| 3 4| | | 1 2 3 4| | 1 2 3 4| +| 5 6 7 8| --> | 5 6| 7 8| | | 5 6 7 8| --> | 5 6 7 8| +| 9 10 11 12| | 9 10| 11 12| | | 9 10 11 12| +------------+ +| 13 14 15 16| | 13 14| 15 16| | | 13 14 15 16| | 9 10 11 12| ++------------+ +------+------+ | +------------+ | 13 14 15 16| + +------------+ +``` + +This set at the very top of the TOML file, like the `channels` parameter +```toml +split_axis=0 + +[caller_settings.dorado] +config = "dna_r10.4.1_e8.2_400bps_hac" +address = "ipc:///tmp/.guppy/5555" +debug_log = "basecalled_chunks.fq" #optional +......... # and so on +``` + +The flongle is a strange shape - 13 columns by 10 rows. 13 is a prime, meaning it cannot be split vertically (except into 13), so flongles must be split horizontally into 2,5 or 10 regions. diff --git a/docs/toml.md b/docs/toml.md index 80846de9..d15e49bc 100644 --- a/docs/toml.md +++ b/docs/toml.md @@ -193,6 +193,8 @@ The number of regions subtables determines how many times the flow cell is divid The maximum number of regions for MinION flow cells is 32 and for PromethION flow cells is 120. The number of conditions must be a factor of the number for the selected combination. +The flongle is a strange shape - 13 columns by 10 rows. 13 is a prime, meaning it cannot be split vertically (except into 13), so flongles must be split horizontally into 2,5 or 10 regions. + As an example applying two analysis regions to the layout below would split the flow cell into left/right regions. ```text +------------+ +------+------+ @@ -202,6 +204,32 @@ As an example applying two analysis regions to the layout below would split the +------------+ +------+------+ ``` +The flow cell can be split both vertically and horizontally, with the `split_axis` parameter in the TOML file deciding this. +The axis can be either 0 or 1, with 0 splitting horizontally and 1 splitting vertically. +The default value is 1, so this only needs setting if you wish to split horizontally. + +```text + Vertical (axis=1) Horizontal (axis=0) ++------------+ +------+------+ | +------------+ +------------+ +| 1 2 3 4| | 1 2| 3 4| | | 1 2 3 4| | 1 2 3 4| +| 5 6 7 8| --> | 5 6| 7 8| | | 5 6 7 8| --> | 5 6 7 8| +| 9 10 11 12| | 9 10| 11 12| | | 9 10 11 12| +------------+ +| 13 14 15 16| | 13 14| 15 16| | | 13 14 15 16| | 9 10 11 12| ++------------+ +------+------+ | +------------+ | 13 14 15 16| + +------------+ +``` + +This set at the very top of the TOML file, like the `channels` parameter +```toml +split_axis=0 + +[caller_settings.dorado] +config = "dna_r10.4.1_e8.2_400bps_hac" +address = "ipc:///tmp/.guppy/5555" +debug_log = "basecalled_chunks.fq" #optional +......... # and so on +``` + ### Experiments with one region When wanting to apply a single targeting strategy over the flow cell a single region can be provided. diff --git a/src/readfish/_config.py b/src/readfish/_config.py index 41603628..b3e0ea76 100644 --- a/src/readfish/_config.py +++ b/src/readfish/_config.py @@ -236,6 +236,7 @@ class Conf: :param channels: The number of channels on the flow cell :param caller_settings: The caller settings as listed in the TOML :param mapper_settings: The mapper settings as listed in the TOML + :param split_axis: The axis on which to split a flowcell if there are multiple regions. 0 is horizontal, 1 is vertical. :param regions: The regions as listed in the Toml file. :param barcodes: A Dictionary of barcode names to Barcode Classes :param _channel_map: A map of channels number (1 to flowcell size) to the index of the Region (in self.regions) they are part of. @@ -244,6 +245,7 @@ class Conf: channels: int caller_settings: CallerSettings mapper_settings: MapperSettings + split_axis: int = 1 regions: List[Region] = attrs.field(default=attrs.Factory(list)) barcodes: Dict[str, Barcode] = attrs.field(default=attrs.Factory(dict)) _channel_map: Dict[int, int] = attrs.field( @@ -281,7 +283,9 @@ def __attrs_post_init__(self): " with n_threads set to at least 4." ) - split_channels = generate_flowcell(self.channels, len(self.regions) or 1) + split_channels = generate_flowcell( + self.channels, len(self.regions) or 1, axis=self.split_axis + ) self._channel_map = { channel: pos for pos, (channels, region) in enumerate(zip(split_channels, self.regions)) @@ -465,7 +469,7 @@ def describe_experiment(self) -> str: description.append( f"""Region {region.name} (control={region.control}). Region applies to section of flow cell (# = applied, . = not applied): -{draw_flowcell_split(self.channels, split, index=index)}""" +{draw_flowcell_split(self.channels, split, index=index, axis=self.split_axis)}""" ) return "\n".join(description) diff --git a/src/readfish/_utils.py b/src/readfish/_utils.py index 4380e661..6792952f 100644 --- a/src/readfish/_utils.py +++ b/src/readfish/_utils.py @@ -282,7 +282,11 @@ def stringify_grid(grid: list[list[str]]) -> str: def draw_flowcell_split( - flowcell_size: int, split: int = 1, axis: int = 1, index: int = 0 + flowcell_size: int, + split: int = 1, + axis: int = 1, + index: int = 0, + prefix: str = "\t", ) -> str: """ Draw unicode representation of the flowcell. If the flowcell is split more than once, and index is passed, the region of the @@ -306,24 +310,53 @@ def draw_flowcell_split( 00XX 00XX + >>> print(draw_flowcell_split(126, 13, index=1, axis=1, prefix="")) + + .#........... + .#........... + .#........... + .#........... + .#........... + + + >>> print(draw_flowcell_split(126, 5, index=1, axis=0, prefix="")) + + ............. + ............. + ............. + ############# + ............. + + :param flowcell_size: Number of channels on the flow cell :param split: The number of regions to split into, defaults to 1 :param index: The index of the region to highlight, defaults to 0 + :param prefix: Any leading string character to put on the row. Defaults to \t :return: String representation of the flowcell in ASCII art """ - depth, width = get_flowcell_array(flowcell_size).shape - depth = round((depth / 2) + 0.5) + height, width = get_flowcell_array(flowcell_size).shape + height = round((height / 2) + 0.5) + # Flongle is a truly dumb shape - 10 rows of 13 columns, breaks maths above so just special case it + if flowcell_size == 126: + height -= 1 cells = [] - for _h in range(depth): + for _h in range(height): row = [ - " ", + prefix, ] for _w in range(width): row.append(".") cells.append(row) cells = np.array(cells) region = generate_flowcell(flowcell_size, split, axis)[index] + col, row = None, None for pos in region: + # Flongle has four channels which are "0", but are just placeholders + # in the array where there is no channel due to it's weird shape. + # Therefore we insert a whitespace for this character + if pos == 0 and flowcell_size == 126: + cells[(col // 2), row + 2] = " " + continue row, col = get_coords(pos, flowcell_size) cells[(col // 2), row + 1] = "#" return f"\n{stringify_grid(cells)}\n" @@ -363,6 +396,14 @@ def generate_flowcell( Traceback (most recent call last): ... ValueError: The flowcell cannot be split evenly + + >>> for x in generate_flowcell(126, 5, axis=0): + ... print(len(x)) + 26 + 26 + 26 + 26 + 26 """ if odd_even: return [ diff --git a/tests/static/describe_test/describe_barcoded_regions_experiment_expected.txt b/tests/static/describe_test/describe_barcoded_regions_experiment_expected.txt index 6eb26ebd..71a25cb4 100644 --- a/tests/static/describe_test/describe_barcoded_regions_experiment_expected.txt +++ b/tests/static/describe_test/describe_barcoded_regions_experiment_expected.txt @@ -5,23 +5,23 @@ Barcode unclassified_reads (control=False), Barcode classified_reads (control=Fa Region Experimental (control=False). Region applies to section of flow cell (# = applied, . = not applied): - ################................ - ################................ - ################................ - ################................ - ################................ - ################................ - ################................ - ################................ + ################................ + ################................ + ################................ + ################................ + ################................ + ################................ + ################................ + ################................ Region Control (control=True). Region applies to section of flow cell (# = applied, . = not applied): - ................################ - ................################ - ................################ - ................################ - ................################ - ................################ - ................################ - ................################ + ................################ + ................################ + ................################ + ................################ + ................################ + ................################ + ................################ + ................################ diff --git a/tests/static/describe_test/describe_experiment_regions_expected.txt b/tests/static/describe_test/describe_experiment_regions_expected.txt index bf19cca9..2518ef9f 100644 --- a/tests/static/describe_test/describe_experiment_regions_expected.txt +++ b/tests/static/describe_test/describe_experiment_regions_expected.txt @@ -2,23 +2,23 @@ Configuration description: Region select two contigs (control=False). Region applies to section of flow cell (# = applied, . = not applied): - ################................ - ################................ - ################................ - ################................ - ################................ - ################................ - ################................ - ################................ + ################................ + ################................ + ################................ + ################................ + ################................ + ################................ + ################................ + ################................ Region control (control=True). Region applies to section of flow cell (# = applied, . = not applied): - ................################ - ................################ - ................################ - ................################ - ................################ - ................################ - ................################ - ................################ + ................################ + ................################ + ................################ + ................################ + ................################ + ................################ + ................################ + ................################