//  [python]
def run_image_pair_images(self, workspace, first_image_name, second_image_name):
        """Calculate the correlation between the pixels of two images"""
        first_image = workspace.image_set.get_image(
            first_image_name, must_be_grayscale=True
        )
        second_image = workspace.image_set.get_image(
            second_image_name, must_be_grayscale=True
        )
        first_pixel_data = first_image.pixel_data
        first_mask = first_image.mask
        first_pixel_count = numpy.prod(first_pixel_data.shape)
        second_pixel_data = second_image.pixel_data
        second_mask = second_image.mask
        second_pixel_count = numpy.prod(second_pixel_data.shape)
        #
        # Crop the larger image similarly to the smaller one
        #
        if first_pixel_count < second_pixel_count:
            second_pixel_data = first_image.crop_image_similarly(second_pixel_data)
            second_mask = first_image.crop_image_similarly(second_mask)
        elif second_pixel_count < first_pixel_count:
            first_pixel_data = second_image.crop_image_similarly(first_pixel_data)
            first_mask = second_image.crop_image_similarly(first_mask)
        mask = (
            first_mask
            & second_mask
            & (~numpy.isnan(first_pixel_data))
            & (~numpy.isnan(second_pixel_data))
        )
        result = []
        if numpy.any(mask):
            fi = first_pixel_data[mask]
            si = second_pixel_data[mask]

            if self.do_corr_and_slope:
                #
                # Perform the correlation, which returns:
                # [ [ii, ij],
                #   [ji, jj] ]
                #
                corr = numpy.corrcoef((fi, si))[1, 0]
                #
                # Find the slope as a linear regression to
                # A * i1 + B = i2
                #
                coeffs = lstsq(numpy.array((fi, numpy.ones_like(fi))).transpose(), si)[
                    0
                ]
                slope = coeffs[0]
                result += [
                    [
                        first_image_name,
                        second_image_name,
                        "-",
                        "Correlation",
                        "%.3f" % corr,
                    ],
                    [first_image_name, second_image_name, "-", "Slope", "%.3f" % slope],
                ]

            if any((self.do_manders, self.do_rwc, self.do_overlap)):
                # Threshold as percentage of maximum intensity in each channel
                thr_fi = self.thr.value * numpy.max(fi) / 100
                thr_si = self.thr.value * numpy.max(si) / 100
                combined_thresh = (fi > thr_fi) & (si > thr_si)
                fi_thresh = fi[combined_thresh]
                si_thresh = si[combined_thresh]
                tot_fi_thr = fi[(fi > thr_fi)].sum()
                tot_si_thr = si[(si > thr_si)].sum()

            if self.do_manders:
                # Manders Coefficient
                M1 = 0
                M2 = 0
                M1 = fi_thresh.sum() / tot_fi_thr
                M2 = si_thresh.sum() / tot_si_thr

                result += [
                    [
                        first_image_name,
                        second_image_name,
                        "-",
                        "Manders Coefficient",
                        "%.3f" % M1,
                    ],
                    [
                        second_image_name,
                        first_image_name,
                        "-",
                        "Manders Coefficient",
                        "%.3f" % M2,
                    ],
                ]

            if self.do_rwc:
                # RWC Coefficient
                RWC1 = 0
                RWC2 = 0
                Rank1 = numpy.lexsort([fi])
                Rank2 = numpy.lexsort([si])
                Rank1_U = numpy.hstack([[False], fi[Rank1[:-1]] != fi[Rank1[1:]]])
                Rank2_U = numpy.hstack([[False], si[Rank2[:-1]] != si[Rank2[1:]]])
                Rank1_S = numpy.cumsum(Rank1_U)
                Rank2_S = numpy.cumsum(Rank2_U)
                Rank_im1 = numpy.zeros(fi.shape, dtype=int)
                Rank_im2 = numpy.zeros(si.shape, dtype=int)
                Rank_im1[Rank1] = Rank1_S
                Rank_im2[Rank2] = Rank2_S

                R = max(Rank_im1.max(), Rank_im2.max()) + 1
                Di = abs(Rank_im1 - Rank_im2)
                weight = ((R - Di) * 1.0) / R
                weight_thresh = weight[combined_thresh]
                RWC1 = (fi_thresh * weight_thresh).sum() / tot_fi_thr
                RWC2 = (si_thresh * weight_thresh).sum() / tot_si_thr
                result += [
                    [
                        first_image_name,
                        second_image_name,
                        "-",
                        "RWC Coefficient",
                        "%.3f" % RWC1,
                    ],
                    [
                        second_image_name,
                        first_image_name,
                        "-",
                        "RWC Coefficient",
                        "%.3f" % RWC2,
                    ],
                ]

            if self.do_overlap:
                # Overlap Coefficient
                overlap = 0
                overlap = (fi_thresh * si_thresh).sum() / numpy.sqrt(
                    (fi_thresh ** 2).sum() * (si_thresh ** 2).sum()
                )
                K1 = (fi_thresh * si_thresh).sum() / (fi_thresh ** 2).sum()
                K2 = (fi_thresh * si_thresh).sum() / (si_thresh ** 2).sum()
                result += [
                    [
                        first_image_name,
                        second_image_name,
                        "-",
                        "Overlap Coefficient",
                        "%.3f" % overlap,
                    ]
                ]

            if self.do_costes:
                # Orthogonal Regression for Costes' automated threshold
                scale = get_scale(first_image.scale, second_image.scale)
                if self.fast_costes == M_FASTER:
                    thr_fi_c, thr_si_c = self.bisection_costes(fi, si, scale)
                else:
                    thr_fi_c, thr_si_c = self.linear_costes(fi, si, scale)

                # Costes' thershold calculation
                combined_thresh_c = (fi > thr_fi_c) & (si > thr_si_c)
                fi_thresh_c = fi[combined_thresh_c]
                si_thresh_c = si[combined_thresh_c]
                tot_fi_thr_c = fi[(fi > thr_fi_c)].sum()
                tot_si_thr_c = si[(si > thr_si_c)].sum()

                # Costes' Automated Threshold
                C1 = 0
                C2 = 0
                C1 = fi_thresh_c.sum() / tot_fi_thr_c
                C2 = si_thresh_c.sum() / tot_si_thr_c

                result += [
                    [
                        first_image_name,
                        second_image_name,
                        "-",
                        "Manders Coefficient (Costes)",
                        "%.3f" % C1,
                    ],
                    [
                        second_image_name,
                        first_image_name,
                        "-",
                        "Manders Coefficient (Costes)",
                        "%.3f" % C2,
                    ],
                ]

        else:
            corr = numpy.NaN
            slope = numpy.NaN
            C1 = numpy.NaN
            C2 = numpy.NaN
            M1 = numpy.NaN
            M2 = numpy.NaN
            RWC1 = numpy.NaN
            RWC2 = numpy.NaN
            overlap = numpy.NaN
            K1 = numpy.NaN
            K2 = numpy.NaN

        #
        # Add the measurements
        #
        if self.do_corr_and_slope:
            corr_measurement = F_CORRELATION_FORMAT % (
                first_image_name,
                second_image_name,
            )
            slope_measurement = F_SLOPE_FORMAT % (first_image_name, second_image_name)
            workspace.measurements.add_image_measurement(corr_measurement, corr)
            workspace.measurements.add_image_measurement(slope_measurement, slope)
        if self.do_overlap:
            overlap_measurement = F_OVERLAP_FORMAT % (
                first_image_name,
                second_image_name,
            )
            k_measurement_1 = F_K_FORMAT % (first_image_name, second_image_name)
            k_measurement_2 = F_K_FORMAT % (second_image_name, first_image_name)
            workspace.measurements.add_image_measurement(overlap_measurement, overlap)
            workspace.measurements.add_image_measurement(k_measurement_1, K1)
            workspace.measurements.add_image_measurement(k_measurement_2, K2)
        if self.do_manders:
            manders_measurement_1 = F_MANDERS_FORMAT % (
                first_image_name,
                second_image_name,
            )
            manders_measurement_2 = F_MANDERS_FORMAT % (
                second_image_name,
                first_image_name,
            )
            workspace.measurements.add_image_measurement(manders_measurement_1, M1)
            workspace.measurements.add_image_measurement(manders_measurement_2, M2)
        if self.do_rwc:
            rwc_measurement_1 = F_RWC_FORMAT % (first_image_name, second_image_name)
            rwc_measurement_2 = F_RWC_FORMAT % (second_image_name, first_image_name)
            workspace.measurements.add_image_measurement(rwc_measurement_1, RWC1)
            workspace.measurements.add_image_measurement(rwc_measurement_2, RWC2)
        if self.do_costes:
            costes_measurement_1 = F_COSTES_FORMAT % (
                first_image_name,
                second_image_name,
            )
            costes_measurement_2 = F_COSTES_FORMAT % (
                second_image_name,
                first_image_name,
            )
            workspace.measurements.add_image_measurement(costes_measurement_1, C1)
            workspace.measurements.add_image_measurement(costes_measurement_2, C2)

        return result