Project: s41467-025-57505-2 | Function: subregion_assembly (python)

system: You are an expert Python programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow Python best practices and maintain consistent code style.
Return **only** the complete Python function code.

user: Complete this Python function:

**DESCRIPTION:** Core haplotype assembly algorithm that extends haplotypes position by position using graph-based assembly. Implements iterative extension with support thresholding and missing haplotype rescue mechanisms.

**KEY TERMS:** {
  "pos1": "starting genomic position",
  "pos2": "ending genomic position",
  "pos1_haps": "assembled haplotypes",
  "thres": "support threshold for filtering",
  "subregion_haps_assembled": "candidate haplotype assemblies"
}

**CONTEXT CODE:**             best_matches = []
            nmatches = []
            for pos in new_nodes:
                _, best_match, max_match = self.get_matching_hap(new_nodes, pos, hap)
                nmatches.append(max_match)
                best_matches.append(best_match)
            if None not in best_matches:
                # if debug:
                #    print(read, hap, best_matches, nmatches)
                num_matches = [len(a) for a in best_matches]
                if num_matches == [1, 1]:
                    joined_haplotype = best_matches[0][0] + "" + best_matches[1][0]
                    sub_hap_support_reads.setdefault(joined_haplotype, []).append(read)
                for a in best_matches[0]:
                    for b in best_matches[1]:
                        dnext.setdefault(a, set()).add(b)
                        dbefore.setdefault(b, set()).add(a)
        return sub_hap_support_reads, dnext, dbefore

    @staticmethod
    def get_missing(subregion_haps_assembled, left_original, right_original):
        """
        find those that cannot span
        Parameters:
            subregion_haps_assembled (lst): assembled haps
            left_original (lst): left candidates
            right_original (lst): right candidates
        Returns:
            left_missing (lst): left candidates missing
            right_missing (lst): right candidates missing
        """
        left_missing = []
        right_missing = []
        for test_hap in left_original:
            found = False
            for ass_hap in subregion_haps_assembled:
                if test_hap == ass_hap[: len(test_hap)]:
                    found = True
            if found is False:
                left_missing.append(test_hap)
        for test_hap in right_original:
            found = False
            for ass_hap in subregion_haps_assembled:
                if test_hap == ass_hap[0 - len(test_hap) :]:
                    found = True
            if found is False:
                right_missing.append(test_hap)
        return left_missing, right_missing

    # get haplotypes between pos1 and pos2
    def subregion_assembly(self, pos1, pos2, allow_x=False, debug=False):
        """
        Core haplotype assembly algorithm for graph-based phasing.

        This function extends haplotypes position by position using graph-based assembly,
        implementing the iterative extension algorithm described in the Paraphase paper.
        It performs haplotype assembly with support thresholding and missing haplotype
        rescue mechanisms to accurately phase paralogous genes from HiFi sequencing data.

        Args:
            pos1 (int): Starting genomic position for assembly
            pos2 (int): Ending genomic position for assembly
            allow_x (bool): Allow missing candidates with x's appended (default: False)
            debug (bool): Enable debug output (default: False)

        Returns:
            tuple: (success_flag, assembled_haplotypes, next_connections, before_connections)
                - success_flag (bool): Whether assembly completed successfully
                - assembled_haplotypes (list): List of assembled haplotype strings
                - next_connections (dict): Forward linkage information
                - before_connections (dict): Backward linkage information

        Raises:
            NotImplementedError: Function has been masked for testing purposes
        """
        raise NotImplementedError("This function has been masked for testing purposes")

    @staticmethod
    def rescue_missing(left_missing, right_missing, dnext, dbefore, debug=False):
        """
        Two scenarios:
        1. there is only one link and that one link is the only one in the other
        missing set, or the other missing set is empty
        2. there can be multiple links but only one of them is in the other missing
        set, and that one link is the only one in the other missing set
        """
        rescued_haps = set()
        for missing_hap in left_missing:
            if missing_hap in dnext and missing_hap.count("x") <= 1:
                possible_links = list(dnext[missing_hap])
                if len(possible_links) == 1 and right_missing in [
                    [],
                    [possible_links[0]],
                ]:
                    if debug:
                        print("merging", missing_hap, possible_links)
                    rescued_haps.add(missing_hap + possible_links[0])
                else:
                    possible_links_also_missing = [
                        a for a in possible_links if a in right_missing
                    ]
                    if (
                        len(possible_links_also_missing) == 1
                        and right_missing == possible_links_also_missing
                        and len(left_missing) == 1
                    ):
                        if debug:
                            print(
                                "merging",
                                missing_hap,
                                possible_links,
                                possible_links_also_missing,
                            )
                        rescued_haps.add(missing_hap + possible_links_also_missing[0])
        for missing_hap in right_missing:
            if missing_hap in dbefore and missing_hap.count("x") <= 1:
                possible_links = list(dbefore[missing_hap])
                if len(possible_links) == 1 and left_missing in [
                    [],
                    [possible_links[0]],
                ]:
                    if debug:
                        print("merging", possible_links, missing_hap)
                    rescued_haps.add(possible_links[0] + missing_hap)
                else:
                    possible_links_also_missing = [
                        a for a in possible_links if a in left_missing
                    ]
                    if (
                        len(possible_links_also_missing) == 1
                        and left_missing == possible_links_also_missing
                        and len(right_missing) == 1
                    ):
                        if debug:
                            print(
                                "merging",
                                possible_links,
                                possible_links_also_missing,
                                missing_hap,
                            )
                        rescued_haps.add(possible_links_also_missing[0] + missing_hap)
        return rescued_haps

    @staticmethod
    def get_matching_hap(new_nodes, pos1, hap):
        """
        Parameters:
            new_nodes (dict): two positions and their associated partial haplotypes
            pos1 (int): positions of interest
            hap (str): full read bases


Complete the function implementation replacing "raise NotImplementedError".