<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def three_layer_FPR(reference_patterns, estimated_patterns):
 """Three Layer F1 Score, Precision and Recall. As described by Meridith. Examples -------- Parameters reference_patterns : list The reference patterns in the format returned by :func:`mir_eval.io.load_patterns()` estimated_patterns : list The estimated patterns in the same format Returns ------- f_measure : float The three-layer F1 Score precision : float The three-layer Precision recall : float The three-layer Recall """

    validate(reference_patterns, estimated_patterns)

    def compute_first_layer_PR(ref_occs, est_occs):
        """Computes the first layer Precision and Recall values given the
        set of occurrences in the reference and the set of occurrences in the
        estimation.

        Parameters
        ----------
        ref_occs :

        est_occs :


        Returns
        -------

        """
        # Find the length of the intersection between reference and estimation
        s = len(_occurrence_intersection(ref_occs, est_occs))

        # Compute the first layer scores
        precision = s / float(len(ref_occs))
        recall = s / float(len(est_occs))
        return precision, recall

    def compute_second_layer_PR(ref_pattern, est_pattern):
        """Computes the second layer Precision and Recall values given the
        set of occurrences in the reference and the set of occurrences in the
        estimation.

        Parameters
        ----------
        ref_pattern :

        est_pattern :


        Returns
        -------

        """
        # Compute the first layer scores
        F_1 = compute_layer(ref_pattern, est_pattern)

        # Compute the second layer scores
        precision = np.mean(np.max(F_1, axis=0))
        recall = np.mean(np.max(F_1, axis=1))
        return precision, recall

    def compute_layer(ref_elements, est_elements, layer=1):
        """Computes the F-measure matrix for a given layer. The reference and
        estimated elements can be either patters or occurrences, depending
        on the layer.

        For layer 1, the elements must be occurrences.
        For layer 2, the elements must be patterns.

        Parameters
        ----------
        ref_elements :

        est_elements :

        layer :
             (Default value = 1)

        Returns
        -------

        """
        if layer != 1 and layer != 2:
            raise ValueError("Layer (%d) must be an integer between 1 and 2"
                             % layer)

        nP = len(ref_elements)      # Number of elements in reference
        nQ = len(est_elements)      # Number of elements in estimation
        F = np.zeros((nP, nQ))      # F-measure matrix for the given layer
        for iP in range(nP):
            for iQ in range(nQ):
                if layer == 1:
                    func = compute_first_layer_PR
                elif layer == 2:
                    func = compute_second_layer_PR

                # Compute layer scores
                precision, recall = func(ref_elements[iP], est_elements[iQ])
                F[iP, iQ] = util.f_measure(precision, recall)
        return F

    # If no patterns were provided, metric is zero
    if _n_onset_midi(reference_patterns) == 0 or \
       _n_onset_midi(estimated_patterns) == 0:
        return 0., 0., 0.

    # Compute the second layer (it includes the first layer)
    F_2 = compute_layer(reference_patterns, estimated_patterns, layer=2)

    # Compute the final scores (third layer)
    precision_3 = np.mean(np.max(F_2, axis=0))
    recall_3 = np.mean(np.max(F_2, axis=1))
    f_measure_3 = util.f_measure(precision_3, recall_3)
    return f_measure_3, precision_3, recall_3