Calculate L-CV and L-SKEW from a single catchment or a pooled group of catchments.

        Methodology source: Science Report SC050050, para. 6.4.1-6.4.2

def _var_and_skew(self, catchments, as_rural=False):
        """
        Calculate L-CV and L-SKEW from a single catchment or a pooled group of catchments.

        Methodology source: Science Report SC050050, para. 6.4.1-6.4.2
        """
        if not hasattr(catchments, '__getitem__'):  # In case of a single catchment
            l_cv, l_skew = self._l_cv_and_skew(self.catchment)
            self.results_log['donors'] = []
        else:
            # Prepare arrays for donor L-CVs and L-SKEWs and their weights
            n = len(catchments)
            l_cvs = np.empty(n)
            l_skews = np.empty(n)
            l_cv_weights = np.empty(n)
            l_skew_weights = np.empty(n)

            # Fill arrays
            for index, donor in enumerate(catchments):
                l_cvs[index], l_skews[index] = self._l_cv_and_skew(donor)
                l_cv_weights[index] = self._l_cv_weight(donor)
                l_skew_weights[index] = self._l_skew_weight(donor)

            # Weighted averages of L-CV and l-SKEW
            l_cv_weights /= sum(l_cv_weights)  # Weights sum to 1
            # Special case if the first donor is the subject catchment itself, assumed if similarity distance == 0.
            if self._similarity_distance(self.catchment, catchments[0]) == 0:
                l_cv_weights *= self._l_cv_weight_factor()  # Reduce weights of all donor catchments
                l_cv_weights[0] += 1 - sum(l_cv_weights)    # But increase the weight of the subject catchment
            l_cv_rural = sum(l_cv_weights * l_cvs)
            l_skew_weights /= sum(l_skew_weights)  # Weights sum to 1
            l_skew_rural = sum(l_skew_weights * l_skews)
            self.results_log['l_cv_rural'] = l_cv_rural
            self.results_log['l_skew_rural'] = l_skew_rural

            if as_rural:
                l_cv = l_cv_rural
                l_skew = l_skew_rural
            else:
                # Method source: eqns. 10 and 11, Kjeldsen 2010
                l_cv = l_cv_rural * 0.5547 ** self.catchment.descriptors.urbext(self.year)
                l_skew = (l_skew_rural + 1) * 1.1545 ** self.catchment.descriptors.urbext(self.year) - 1

            # Record intermediate results (donors)
            self.results_log['donors'] = catchments
            total_record_length = 0
            for index, donor in enumerate(self.results_log['donors']):
                donor.l_cv = l_cvs[index]
                donor.l_cv_weight = l_cv_weights[index]
                donor.l_skew = l_skews[index]
                donor.l_skew_weight = l_skew_weights[index]
                total_record_length += donor.record_length
            self.results_log['donors_record_length'] = total_record_length

        # Record intermediate results
        self.results_log['l_cv'] = l_cv
        self.results_log['l_skew'] = l_skew
        return l_cv, l_skew