def _detect_correlation(self):
correlations = []<EOL>shifted_correlations = []<EOL>self.time_series_a.normalize()<EOL>self.time_series_b.normalize()<EOL>a, b = self.time_series_a.align(self.time_series_b)<EOL>a_values, b_values = a.values, b.values<EOL>a_avg, b_avg = a.average(), b.average()<EOL>a_stdev, b_stdev = a.stdev(), b.stdev()<EOL>n = len(a)<EOL>denom = a_stdev * b_stdev * n<EOL>allowed_shift_step = self._find_allowed_shift(a.timestamps)<EOL>if allowed_shift_step:<EOL><INDENT>shift_upper_bound = allowed_shift_step<EOL>shift_lower_bound = -allowed_shift_step<EOL><DEDENT>else:<EOL><INDENT>shift_upper_bound = <NUM_LIT:1><EOL>shift_lower_bound = <NUM_LIT:0><EOL><DEDENT>for delay in range(shift_lower_bound, shift_upper_bound):<EOL><INDENT>delay_in_seconds = a.timestamps[abs(delay)] - a.timestamps[<NUM_LIT:0>]<EOL>if delay < <NUM_LIT:0>:<EOL><INDENT>delay_in_seconds = -delay_in_seconds<EOL><DEDENT>s = <NUM_LIT:0><EOL>for i in range(n):<EOL><INDENT>j = i + delay<EOL>if j < <NUM_LIT:0> or j >= n:<EOL><INDENT>continue<EOL><DEDENT>else:<EOL><INDENT>s += ((a_values[i] - a_avg) * (b_values[j] - b_avg))<EOL><DEDENT><DEDENT>r = s / denom if denom != <NUM_LIT:0> else s<EOL>correlations.append([delay_in_seconds, r])<EOL>if self.max_shift_milliseconds:<EOL><INDENT>shifted_correlations.append(r * (<NUM_LIT:1> + float(delay_in_seconds) / self.max_shift_milliseconds * self.shift_impact))<EOL><DEDENT>else:<EOL><INDENT>shifted_correlations.append(r)<EOL><DEDENT><DEDENT>max_correlation = list(max(correlations, key=lambda k: k[<NUM_LIT:1>]))<EOL>max_shifted_correlation = max(shifted_correlations)<EOL>max_correlation.append(max_shifted_correlation)<EOL>self.correlation_result = CorrelationResult(*max_correlation)<EOL>
Detect correlation by computing correlation coefficients for all allowed shift steps,
then take the maximum.