Project: s41467-025-60491-0 | Function: calcOffTargetScore (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:** 

**KEY TERMS:** {}

**CONTEXT CODE:**                               'C20': 0.0151, 'G17': 0.0155, 'G18': 0.0165, 'T30': 0.0173, 'A13': 0.0176, 'G19': 0.0179,
                              'A27': 0.0191, 'G11': 0.0209, 'TG3': 0.0229,
                              'GC3': 0.0247, 'G14': 0.0251, 'GG10': 0.0268, 'G12': 0.0276, 'G32': 0.0307, 'A22': 0.0319,
                              'G20': 0.0340, 'C21': 0.0343, 'TT17': 0.0349,
                              'T13': 0.0354, 'G26': 0.0361, 'A24': 0.0375, 'C22': 0.0376, 'G16': 0.0380, 'GG12': 0.0419,
                              'TG18': 0.0459, 'TG31': 0.0481, 'A35': 0.0486,
                              'G15': 0.0511, 'C24': 0.0530, 'TG15': 0.0534, 'GT11': 0.0537, 'GC9': 0.0542,
                              'CA30': 0.0578, 'GT24': 0.0610, 'G13': 0.0614, 'CA24': 0.0622,
                              'AG10': 0.0637, 'G10': 0.0677, 'C13': 0.0695, 'GT31': 0.0734, 'GG13': 0.0744,
                              'C27': 0.0799, 'G27': 0.0852, 'CC21': 0.0889, 'CC23': 0.0951,
                              'G22': 0.1011, 'G24': 0.1055, 'GT23': 0.1067, 'GG25': 0.1116, 'G9': 0.1146}
    PAMDensityScoreMatrix = [[1, 1, 1, 2, 2, 8, 10],
                             [1, 1, 1, 2, 2, 8, 10],
                             [1, 1, 1, 2.5, 2.5, 10, -1],
                             [1, 1, 1.66, 2.5, 2.5, -1, -1],
                             [1.66, 1.66, 3.33, 3.33, -1, -1, -1],
                             [2.5, 2.5, 3.33, -1, -1, -1, -1],
                             [5, 5, -1, -1, -1, -1, -1]]

    def __init__(self, spacerOrTargetSequence, genome):
        """Initialization method that takes in a 23 bp DNA spacer/target or a 20 bp DNA spacer/target sequence,
        and (2) an associated metaGenome class file, and instantiates, checking to ensure the guideSequence is in the
        proper format (6 bp upstream, 20 bp spacer sequence, 3 bp PAM, 6 bp downstream), as well as that given genome
        is a MetaGenome, trying to complete the guideSequence using the genome otherwise. """
        self.__spacerSequence = ""  # RNA string of length 23
        self.__onTargetSequences = []  # List of length A with DNA strings of length 35
        self.__onTargetScores = []  # List of length A with doubles
        self.__targets = [] # List of TargetSequence class objects, some on-targets, some off-targets
        if not isinstance(genome, MetaGenome):
            return
        if not isValidTargetSpacerInput(spacerOrTargetSequence):
            print("Input sequence is not a valid spacer sequence: " + spacerOrTargetSequence)
            return
        self.__spacerSequence = convertToDNA(spacerOrTargetSequence[0:20])
        targetSequencesInfo, self.total_alignments = genome.bowtieFindTargetsFromSpacer(self.__spacerSequence)
        for targetSequenceInfo in targetSequencesInfo: # Instantiate all target sequences and calculate on-target scores
            targetInstance = TargetSequence(self, targetSequenceInfo[0], targetSequenceInfo[1])
            if targetInstance.sequence_type == "On-Target":
                targetInstance.calculateScores()
                self.__onTargetScores.append(targetInstance.on_target_score)
            self.__targets.append(targetInstance)

        for targetSequence in self.__targets: # Now calculate off-target scores (which require an on-target)
            if targetSequence.sequence_type == "Off-Target":
                targetSequence.calculateScores()

    def calcOnTargetScore(self, targetSequence):
        # MASKED: Calculates on-target CRISPR-Cas9 efficacy score for guide RNA sequences using CRISPRscan algorithm with nucleotide features and PAM density scoring implementation
        raise NotImplementedError("This function is masked for testing purposes.")

    def calcOffTargetScore(self, offTargetSequence, onTargetScore):
        # MASKED: Calculates off-target CRISPR-Cas9 binding specificity score using Hsu matrix mismatch penalties and proximity-weighted scoring algorithm implementation
        raise NotImplementedError("This function is masked for testing purposes.")

    def calcOffTargetEstimate(self, offTargetSequence):
        """Method that takes in a 35 bp string DNA potential off-target sequence and returns an estimate of the
        calculated off-target score of the given off-target sequence (without using a reference guide sequence) if
        a potential RNA guide sequence containing the class spacer sequence were to attempt binding."""
        if len(offTargetSequence) != 35:
            return 1
        HsuMismatchSubscore = 1
        proximityMismatchSubscore = 0
        steppedProximityMismatchSubscore = 1
        offTargetSpacerSequence = offTargetSequence[6:26]
        for c in range(len(offTargetSpacerSequence)):
            if convertToDNA(self.__spacerSequence[c]) != offTargetSpacerSequence[c]:
                proximityMismatchSubscore = proximityMismatchSubscore + 1 / (20 - c)
                if c > 0:
                    mismatchIdentity = convertToDNA(self.__spacerSequence[c]) + '->' + \
                                       complementaryDNA(offTargetSpacerSequence[c])
                    if mismatchIdentity in self.HsuMatrix:
                        indexDict = self.MismatchToHsuIndexDict[mismatchIdentity]
                        HsuMismatchSubscore = HsuMismatchSubscore * self.HsuMatrix[indexDict][c - 1]
                if 20 - c <= 6:
                    steppedProximityMismatchSubscore = steppedProximityMismatchSubscore - 0.1
                elif 20 - c <= 12:
                    steppedProximityMismatchSubscore = steppedProximityMismatchSubscore - 0.05
                else:
                    steppedProximityMismatchSubscore = steppedProximityMismatchSubscore - 0.0125
        proximityMismatchSubscore = (3.5477 - proximityMismatchSubscore) / 3.5477
        return 200 * (math.sqrt(HsuMismatchSubscore) + steppedProximityMismatchSubscore) \
               * (proximityMismatchSubscore ** 6) / 4

    def __calcHeuristics(self):
        """Method that takes in an instance on-target score and an instance list of off-target scores, and calculates a
        general heuristic to measure the effectiveness of the guide sequence. """
        heuristic = 0
        return heuristic

    def getTotalAlignments(self):
        """Method that returns the total number of alignments (on-targets, off-targets, and those without PAMs)
         of the instance."""
        return self.total_alignments


    def getSpacerSequence(self):
        """Method that returns the 20 bp string RNA spacer sequence of the instance."""
        return self.__spacerSequence

    def getOnTargetSequences(self):
        """Method that returns the list of 35 bp string RNA guide sequences of the instance."""
        on_target_sequences = []
        for targetSequence in self.__targets:
            if targetSequence.sequence_type == "On-Target":
                on_target_sequences.append(targetSequence.target_sequence)
        return on_target_sequences

    def getOffTargetSequences(self):
        """Method that returns the 35 bp string DNA off-target sequences of the instance."""
        off_target_sequences = []
        for targetSequence in self.__targets:
            if targetSequence.sequence_type == "Off-Target":
                off_target_sequences.append(targetSequence.target_sequence)
        return off_target_sequences

    def getOnTargetScores(self):
        """Getter method that returns the calculated on target score."""
        on_target_scores = []
        for targetSequence in self.__targets:
            if targetSequence.sequence_type == "On-Target":
                on_target_scores.append(targetSequence.on_target_score)
        return on_target_scores

    def getOffTargetScores(self):
        """Getter method that returns the calculated off target scores."""
        off_target_scores = []
        for targetSequence in self.__targets:
            if targetSequence.sequence_type == "Off-Target":
                off_target_scores.append(targetSequence.off_target_score)
        return off_target_scores

    def getTargets(self):
        return self.__targets

    def getHeuristics(self):
        """Getter method that returns the calculated heuristic of the guideSequence."""
        return self.__heuristics


Complete the function implementation replacing "raise NotImplementedError".