def flip_measure_regression(self, i, snp, min_clique_size=3, small_clique=10): '''Suggested by Oren. Flip measure for sample i at a snp. This is the separation angle between the regression slopes of the kinship coefficient of clique-father vs. the kinship coefficient of clique-mother for each of the two cliques. The angle is scaled to [-1,1].''' c0, c1 = self.ibd_clique_sample_ids(i, snp, 0), self.ibd_clique_sample_ids(i, snp, 1) if min(c0.shape[0], c1.shape[0]) < min_clique_size: sep, k, line, c = None, None, None, None else: c = [c0, c1] parents = [self.ped.sample_id[self.ped.graph.predecessors(i)[a]] for a in im.constants.ALLELES] K = lambda k, l: np.array([self.params.kinship(parents[k], x) for x in c[l]]) # Perform least-squares fit of both cliques # k_threshold = Aligner._K_THRESHOLD prob = [0.25, 0.75] # Quantile region to include in fit k00 = K(0, 0) k10 = K(1, 0) # good = (k00 <= k_threshold) | (k10 <= k_threshold) m0, m1 = mquantiles(k00, prob=prob), mquantiles(k10, prob=prob) good = (k00 >= m0[0]) & (k00 <= m0[1]) & (k10 >= m1[0]) & (k10 <= m1[1]) if len(c0) >= small_clique else np.arange(len(c0)) a0, b0 = linefit(k00[good], k10[good], 1) # print len(c0), np.where(good)[0] k01 = K(0, 1) k11 = K(1, 1) # good = (k01 <= k_threshold) | (k11 <= k_threshold) m0, m1 = mquantiles(k01, prob=prob), mquantiles(k11, prob=prob) good = (k01 >= m0[0]) & (k01 <= m0[1]) & (k11 >= m1[0]) & (k11 <= m1[1]) if len(c1) >= small_clique else np.arange(len(c1)) a1, b1 = linefit(k01[good], k11[good], 1) # print len(c1), np.where(good)[0] k = (k00, k10, k01, k11) line = (a0, b0, a1, b1) # Calculate the separation angle if np.abs(a0 - a1) < 1e-15: sep = 0 else: e = (b1 - b0) / (a0 - a1) p, q = e, a0 * e + b0 x0 = np.sign(a0 + b0) sep = max(-1, min(1, ANGLE_SCALING_FACTOR * (np.arctan2(a0 * x0 + b0 - q, x0 - p) - np.arctan2(a1 + b1 - q, 1 - p)))) return sep, (len(c0), len(c1)), (k, line, c)
def test_linefit(self): """Test the outlier-resistant line fitter.""" x = numpy.linspace(-10, 10, 256) y = 1.34*x + 0.56 cc = robust.linefit(x, y) self.assertAlmostEqual(cc[0], 1.34, 2) self.assertAlmostEqual(cc[1], 0.56, 2) cc = robust.linefit(x, y, Bisector=True) self.assertAlmostEqual(cc[0], 1.34, 2) self.assertAlmostEqual(cc[1], 0.56, 2) x = numpy.linspace(-10, 10, 2048) y = 2.86*x - 0.56 cc = robust.linefit(x, y) self.assertAlmostEqual(cc[0], 2.86, 2) self.assertAlmostEqual(cc[1], -0.56, 2) cc = robust.linefit(x, y, Bisector=True) self.assertAlmostEqual(cc[0], 2.86, 2) self.assertAlmostEqual(cc[1], -0.56, 2)
def flip_measure_regression(self, i, snp, min_clique_size=3, small_clique=10): '''Suggested by Oren. Flip measure for sample i at a snp. This is the separation angle between the regression slopes of the kinship coefficient of clique-father vs. the kinship coefficient of clique-mother for each of the two cliques. The angle is scaled to [-1,1].''' c0, c1 = self.ibd_clique_sample_ids(i, snp, 0), self.ibd_clique_sample_ids( i, snp, 1) if min(c0.shape[0], c1.shape[0]) < min_clique_size: sep, k, line, c = None, None, None, None else: c = [c0, c1] parents = [ self.ped.sample_id[self.ped.graph.predecessors(i)[a]] for a in im.constants.ALLELES ] K = lambda k, l: np.array( [self.params.kinship(parents[k], x) for x in c[l]]) # Perform least-squares fit of both cliques # k_threshold = Aligner._K_THRESHOLD prob = [0.25, 0.75] # Quantile region to include in fit k00 = K(0, 0) k10 = K(1, 0) # good = (k00 <= k_threshold) | (k10 <= k_threshold) m0, m1 = mquantiles(k00, prob=prob), mquantiles(k10, prob=prob) good = (k00 >= m0[0]) & (k00 <= m0[1]) & (k10 >= m1[0]) & ( k10 <= m1[1]) if len(c0) >= small_clique else np.arange( len(c0)) a0, b0 = linefit(k00[good], k10[good], 1) # print len(c0), np.where(good)[0] k01 = K(0, 1) k11 = K(1, 1) # good = (k01 <= k_threshold) | (k11 <= k_threshold) m0, m1 = mquantiles(k01, prob=prob), mquantiles(k11, prob=prob) good = (k01 >= m0[0]) & (k01 <= m0[1]) & (k11 >= m1[0]) & ( k11 <= m1[1]) if len(c1) >= small_clique else np.arange( len(c1)) a1, b1 = linefit(k01[good], k11[good], 1) # print len(c1), np.where(good)[0] k = (k00, k10, k01, k11) line = (a0, b0, a1, b1) # Calculate the separation angle if np.abs(a0 - a1) < 1e-15: sep = 0 else: e = (b1 - b0) / (a0 - a1) p, q = e, a0 * e + b0 x0 = np.sign(a0 + b0) sep = max( -1, min( 1, ANGLE_SCALING_FACTOR * (np.arctan2(a0 * x0 + b0 - q, x0 - p) - np.arctan2(a1 + b1 - q, 1 - p)))) return sep, (len(c0), len(c1)), (k, line, c)