def test_run_refine_fastmatch_zeroshift(lt_ctx): shape = np.array([128, 128]) zero = shape / 2 + np.random.uniform(-1, 1, size=2) a = np.array([27.17, 0.]) + np.random.uniform(-1, 1, size=2) b = np.array([0., 29.19]) + np.random.uniform(-1, 1, size=2) indices = np.mgrid[-2:3, -2:3] indices = np.concatenate(indices.T) drop = np.random.choice([True, False], size=len(indices), p=[0.9, 0.1]) indices = indices[drop] radius = 10 # Exactly between peaks, worst case shift = (a + b) / 2 data_0, indices_0, peaks_0 = cbed_frame(*shape, zero, a, b, indices, radius) data_1, indices_1, peaks_1 = cbed_frame(*shape, zero + shift, a, b, indices, radius) data = np.concatenate((data_0, data_1), axis=0) dataset = MemoryDataSet(data=data, tileshape=(1, *shape), num_partitions=1, sig_dims=2) matcher = grm.Matcher() match_patterns = [ # Least reliable pattern common.patterns.Circular(radius=radius), ] print("zero: ", zero) print("a: ", a) print("b: ", b) for match_pattern in match_patterns: print("refining using template %s" % type(match_pattern)) zero_shift = np.array([(0., 0.), shift]).astype(np.float32) (res, real_indices) = udf.refinement.run_refine( ctx=lt_ctx, dataset=dataset, zero=zero + np.random.uniform(-1, 1, size=2), a=a + np.random.uniform(-1, 1, size=2), b=b + np.random.uniform(-1, 1, size=2), matcher=matcher, match_pattern=match_pattern, zero_shift=UDF.aux_data(zero_shift, kind='nav', extra_shape=(2, ))) print(peaks_0 - grm.calc_coords(res['zero'].data[0], res['a'].data[0], res['b'].data[0], indices_0)) print(peaks_1 - grm.calc_coords(res['zero'].data[1], res['a'].data[1], res['b'].data[1], indices_1)) assert np.allclose(res['zero'].data[0], zero, atol=0.5) assert np.allclose(res['zero'].data[1], zero + shift, atol=0.5) assert np.allclose(res['a'].data, a, atol=0.2) assert np.allclose(res['b'].data, b, atol=0.2)
def test_featurevector(lt_ctx): shape = np.array([128, 128]) zero = shape // 2 a = np.array([24, 0.]) b = np.array([0., 30]) indices = np.mgrid[-2:3, -2:3] indices = np.concatenate(indices.T) radius = 5 radius_outer = 10 template = m.background_subtraction(centerX=radius_outer + 1, centerY=radius_outer + 1, imageSizeX=radius_outer * 2 + 2, imageSizeY=radius_outer * 2 + 2, radius=radius_outer, radius_inner=radius + 1, antialiased=False) data, indices, peaks = cbed_frame(*shape, zero, a, b, indices, radius, all_equal=True) dataset = MemoryDataSet(data=data, tileshape=(1, *shape), num_partitions=1, sig_dims=2) match_pattern = blobfinder.UserTemplate(template=template) stack = functools.partial( blobfinder.feature_vector, imageSizeX=shape[1], imageSizeY=shape[0], peaks=peaks, match_pattern=match_pattern, ) job = lt_ctx.create_mask_job(dataset=dataset, factories=stack, mask_count=len(peaks), mask_dtype=np.float32) res = lt_ctx.run(job) peak_data, _, _ = cbed_frame(*shape, zero, a, b, np.array([(0, 0)]), radius, all_equal=True) peak_sum = peak_data.sum() assert np.allclose(res.sum(), data.sum()) assert np.allclose(res, peak_sum)
def test_integration(lt_ctx): indices = np.mgrid[-3:4, -3:4] a = (15, 1) b = (-1, 17) zero = (62, 63) data = np.zeros((2, 2, 128, 128), dtype=np.float32) peaks = np.zeros((2, 2, 49, 2), dtype=np.int) # Frame with a single peak ref_frame, _, _ = cbed_frame( fy=128, fx=128, zero=zero, a=a, b=b, indices=np.mgrid[0:1, 0:1], radius=4, all_equal=True, margin=2 ) # Generate frames where the peaks are # shifted individually so that a common integration # with a feature vector wouldn't work for y in range(2): for x in range(2): (data[y, x], _, peaks[y, x]) = cbed_frame( fy=128, fx=128, zero=(zero[0] + 3*y, zero[1] + 4*x), a=(a[0] - y, a[1]), b=(b[0], b[1] - x), indices=indices, radius=4, all_equal=True, margin=2 ) data += 1 # add background ds = lt_ctx.load("memory", data=data, num_partitions=2) centers = libertem_blobfinder.udf.integration.IntegrationUDF.aux_data( data=peaks, kind='nav', dtype=np.int, extra_shape=peaks.shape[-2:] ) udf = libertem_blobfinder.udf.integration.IntegrationUDF( centers=centers, pattern=libertem_blobfinder.common.patterns.BackgroundSubtraction( radius=5, radius_outer=6 ) ) res = lt_ctx.run_udf(udf=udf, dataset=ds) # Make sure the integration result matches exactly the sum of one peak assert np.allclose(ref_frame.sum(), res['integration'].data) assert res['integration'].data.shape == peaks.shape[:-1]
def test_correlation_methods(lt_ctx, cls, dtype, kwargs): shape = np.array([128, 128]) zero = shape / 2 + np.random.uniform(-1, 1, size=2) a = np.array([27.17, 0.]) + np.random.uniform(-1, 1, size=2) b = np.array([0., 29.19]) + np.random.uniform(-1, 1, size=2) indices = np.mgrid[-2:3, -2:3] indices = np.concatenate(indices.T) radius = 8 data, indices, peaks = cbed_frame(*shape, zero, a, b, indices, radius) dataset = MemoryDataSet(data=data, tileshape=(1, *shape), num_partitions=1, sig_dims=2) template = m.radial_gradient( centerX=radius+1, centerY=radius+1, imageSizeX=2*radius+2, imageSizeY=2*radius+2, radius=radius ) match_patterns = [ common.patterns.RadialGradient(radius=radius), common.patterns.Circular(radius=radius), common.patterns.BackgroundSubtraction(radius=radius), common.patterns.RadialGradientBackgroundSubtraction(radius=radius), common.patterns.UserTemplate(template=template) ] print("zero: ", zero) print("a: ", a) print("b: ", b) for match_pattern in match_patterns: print("refining using template %s" % type(match_pattern)) if cls is udf.correlation.SparseCorrelationUDF and kwargs.get('zero_shift'): with pytest.raises(ValueError): m_udf = cls(match_pattern=match_pattern, peaks=peaks.astype(dtype), **kwargs) else: m_udf = cls(match_pattern=match_pattern, peaks=peaks.astype(dtype), **kwargs) res = lt_ctx.run_udf(dataset=dataset, udf=m_udf) print(peaks) print(res['refineds'].data[0]) print(peaks - res['refineds'].data[0]) print(res['peak_values'].data[0]) print(res['peak_elevations'].data[0]) # import matplotlib.pyplot as plt # fig, ax = plt.subplots() # plt.imshow(data[0]) # for p in np.flip(res['refineds'].data[0], axis=-1): # ax.add_artist(plt.Circle(p, radius, fill=False, color='y')) # plt.show() assert np.allclose(res['refineds'].data[0], peaks, atol=0.5)
def test_run_refine_fastmatch(lt_ctx, progress): shape = np.array([128, 128]) zero = shape / 2 + np.random.uniform(-1, 1, size=2) a = np.array([27.17, 0.]) + np.random.uniform(-1, 1, size=2) b = np.array([0., 29.19]) + np.random.uniform(-1, 1, size=2) indices = np.mgrid[-2:3, -2:3] indices = np.concatenate(indices.T) drop = np.random.choice([True, False], size=len(indices), p=[0.9, 0.1]) indices = indices[drop] radius = 10 data, indices, peaks = cbed_frame(*shape, zero, a, b, indices, radius) dataset = MemoryDataSet(data=data, tileshape=(1, *shape), num_partitions=1, sig_dims=2) matcher = grm.Matcher() template = m.radial_gradient(centerX=radius + 1, centerY=radius + 1, imageSizeX=2 * radius + 2, imageSizeY=2 * radius + 2, radius=radius) match_patterns = [ common.patterns.RadialGradient(radius=radius), common.patterns.Circular(radius=radius), common.patterns.BackgroundSubtraction(radius=radius), common.patterns.RadialGradientBackgroundSubtraction(radius=radius), common.patterns.UserTemplate(template=template) ] print("zero: ", zero) print("a: ", a) print("b: ", b) for match_pattern in match_patterns: print("refining using template %s" % type(match_pattern)) (res, real_indices) = udf.refinement.run_refine( ctx=lt_ctx, dataset=dataset, zero=zero + np.random.uniform(-1, 1, size=2), a=a + np.random.uniform(-1, 1, size=2), b=b + np.random.uniform(-1, 1, size=2), matcher=matcher, match_pattern=match_pattern, progress=progress) print(peaks - grm.calc_coords(res['zero'].data[0], res['a'].data[0], res['b'].data[0], indices)) assert np.allclose(res['zero'].data[0], zero, atol=0.5) assert np.allclose(res['a'].data[0], a, atol=0.2) assert np.allclose(res['b'].data[0], b, atol=0.2)
def test_run_refine_affinematch(lt_ctx): for i in range(1): try: shape = np.array([128, 128]) zero = shape / 2 + np.random.uniform(-1, 1, size=2) a = np.array([27.17, 0.]) + np.random.uniform(-1, 1, size=2) b = np.array([0., 29.19]) + np.random.uniform(-1, 1, size=2) indices = np.mgrid[-2:3, -2:3] indices = np.concatenate(indices.T) radius = 10 data, indices, peaks = cbed_frame(*shape, zero, a, b, indices, radius) dataset = MemoryDataSet(data=data, tileshape=(1, *shape), num_partitions=1, sig_dims=2) matcher = grm.Matcher() match_pattern = common.patterns.RadialGradient(radius=radius) affine_indices = peaks - zero for j in range(5): zzero = zero + np.random.uniform(-1, 1, size=2) aa = np.array([1, 0]) + np.random.uniform(-0.05, 0.05, size=2) bb = np.array([0, 1]) + np.random.uniform(-0.05, 0.05, size=2) (res, real_indices) = udf.refinement.run_refine( ctx=lt_ctx, dataset=dataset, zero=zzero, a=aa, b=bb, indices=affine_indices, matcher=matcher, match_pattern=match_pattern, match='affine') assert np.allclose(res['zero'].data[0], zero, atol=0.5) assert np.allclose(res['a'].data[0], [1, 0], atol=0.05) assert np.allclose(res['b'].data[0], [0, 1], atol=0.05) except Exception: print("zero = np.array([%s, %s])" % tuple(zero)) print("a = np.array([%s, %s])" % tuple(a)) print("b = np.array([%s, %s])" % tuple(b)) print("zzero = np.array([%s, %s])" % tuple(zzero)) print("aa = np.array([%s, %s])" % tuple(aa)) print("bb = np.array([%s, %s])" % tuple(bb)) raise
def test_correlation_method_fullframe(lt_ctx, cls, dtype, kwargs): shape = np.array([128, 128]) zero = shape / 2 + np.random.uniform(-1, 1, size=2) a = np.array([34.3, 0.]) + np.random.uniform(-1, 1, size=2) b = np.array([0., 42.19]) + np.random.uniform(-1, 1, size=2) indices = np.mgrid[-2:3, -2:3] indices = np.concatenate(indices.T) radius = 8 data, indices, peaks = cbed_frame(*shape, zero, a, b, indices, radius) dataset = MemoryDataSet(data=data, tileshape=(1, *shape), num_partitions=1, sig_dims=2) template = m.radial_gradient(centerX=radius + 1, centerY=radius + 1, imageSizeX=2 * radius + 2, imageSizeY=2 * radius + 2, radius=radius) match_patterns = [ blobfinder.RadialGradient(radius=radius, search=radius * 1.5), blobfinder.BackgroundSubtraction(radius=radius, radius_outer=radius * 1.5, search=radius * 1.8), blobfinder.RadialGradientBackgroundSubtraction(radius=radius, radius_outer=radius * 1.5, search=radius * 1.8), blobfinder.UserTemplate(template=template, search=radius * 1.5) ] print("zero: ", zero) print("a: ", a) print("b: ", b) for match_pattern in match_patterns: print("refining using template %s" % type(match_pattern)) udf = cls(match_pattern=match_pattern, peaks=peaks.astype(dtype), **kwargs) res = lt_ctx.run_udf(dataset=dataset, udf=udf) print(peaks - res['refineds'].data[0]) # import matplotlib.pyplot as plt # fig, ax = plt.subplots() # plt.imshow(data[0]) # for p in np.flip(res['refineds'].data[0], axis=-1): # ax.add_artist(plt.Circle(p, radius, fill=False, color='y')) # plt.show() assert np.allclose(res['refineds'].data[0], peaks, atol=0.5)
def test_visualize_smoke(navshape, lt_ctx): shape = np.array([128, 128]) zero = shape / 2 + np.random.uniform(-1, 1, size=2) a = np.array([27.17, 0.]) + np.random.uniform(-1, 1, size=2) b = np.array([0., 29.19]) + np.random.uniform(-1, 1, size=2) indices = np.mgrid[-2:3, -2:3] indices = np.concatenate(indices.T) radius = 10 data, indices, peaks = cbed_frame(*shape, zero, a, b, indices, radius) data = data.reshape((*navshape, *shape)) dataset = MemoryDataSet(data=data, tileshape=(1, *shape), num_partitions=1, sig_dims=2) matcher = grm.Matcher() match_pattern = common.patterns.RadialGradientBackgroundSubtraction( radius=radius) print("zero: ", zero) print("a: ", a) print("b: ", b) (res, real_indices) = udf.refinement.run_refine( ctx=lt_ctx, dataset=dataset, zero=zero + np.random.uniform(-1, 1, size=2), a=a + np.random.uniform(-1, 1, size=2), b=b + np.random.uniform(-1, 1, size=2), matcher=matcher, match_pattern=match_pattern) fig, axes = plt.subplots() if len(navshape) == 1: y = None elif len(navshape) == 2: y = 0 else: raise ValueError( f"Nav shape too long, supported are 1D and 2D: {navshape}") udf.utils.visualize_frame(ctx=lt_ctx, ds=dataset, result=res, indices=real_indices, r=radius, y=y, x=0, axes=axes)
def test_run_refine_fastmatch(lt_ctx): shape = np.array([256, 256]) zero = shape / 2 + np.random.uniform(-1, 1, size=2) a = np.array([27.17, 0.]) + np.random.uniform(-1, 1, size=2) b = np.array([0., 29.19]) + np.random.uniform(-1, 1, size=2) indices = np.mgrid[-3:4, -3:4] indices = np.concatenate(indices.T) radius = 10 data, indices, peaks = cbed_frame(*shape, zero, a, b, indices, radius) dataset = MemoryDataSet(data=data, tileshape=(1, *shape), num_partitions=1, sig_dims=2) matcher = grm.Matcher() template = m.radial_gradient(centerX=radius + 1, centerY=radius + 1, imageSizeX=2 * radius + 2, imageSizeY=2 * radius + 2, radius=radius) match_patterns = [ blobfinder.RadialGradient(radius=radius), blobfinder.BackgroundSubtraction(radius=radius), blobfinder.RadialGradientBackgroundSubtraction(radius=radius), blobfinder.UserTemplate(template=template) ] print("zero: ", zero) print("a: ", a) print("b: ", b) for match_pattern in match_patterns: print("refining using template %s" % type(match_pattern)) (res, real_indices) = blobfinder.run_refine( ctx=lt_ctx, dataset=dataset, zero=zero + np.random.uniform(-1, 1, size=2), a=a + np.random.uniform(-1, 1, size=2), b=b + np.random.uniform(-1, 1, size=2), matcher=matcher, match_pattern=match_pattern) print(peaks - grm.calc_coords(res['zero'].data[0], res['a'].data[0], res['b'].data[0], indices)) assert np.allclose(res['zero'].data[0], zero, atol=0.5) assert np.allclose(res['a'].data[0], a, atol=0.2) assert np.allclose(res['b'].data[0], b, atol=0.2)
def test_run_refine_sparse(lt_ctx): shape = np.array([128, 128]) zero = shape / 2 + np.random.uniform(-1, 1, size=2) a = np.array([27.17, 0.]) + np.random.uniform(-1, 1, size=2) b = np.array([0., 29.19]) + np.random.uniform(-1, 1, size=2) indices = np.mgrid[-2:3, -2:3] indices = np.concatenate(indices.T) radius = 10 data, indices, peaks = cbed_frame(*shape, zero, a, b, indices, radius) dataset = MemoryDataSet(data=data, tileshape=(1, *shape), num_partitions=1, sig_dims=2) matcher = grm.Matcher() match_pattern = common.patterns.RadialGradient(radius=radius) print("zero: ", zero) print("a: ", a) print("b: ", b) (res, real_indices) = udf.refinement.run_refine( ctx=lt_ctx, dataset=dataset, zero=zero + np.random.uniform(-0.5, 0.5, size=2), a=a + np.random.uniform(-0.5, 0.5, size=2), b=b + np.random.uniform(-0.5, 0.5, size=2), matcher=matcher, match_pattern=match_pattern, correlation='sparse', steps=3 ) print(peaks - grm.calc_coords( res['zero'].data[0], res['a'].data[0], res['b'].data[0], indices) ) assert np.allclose(res['zero'].data[0], zero, atol=0.5) assert np.allclose(res['a'].data[0], a, atol=0.2) assert np.allclose(res['b'].data[0], b, atol=0.2)
def test_standalone_full(): shape = np.array([128, 128]) zero = shape / 2 + np.random.uniform(-1, 1, size=2) a = np.array([34.3, 0.]) + np.random.uniform(-1, 1, size=2) b = np.array([0., 42.19]) + np.random.uniform(-1, 1, size=2) indices = np.mgrid[-2:3, -2:3] indices = np.concatenate(indices.T) radius = 8 data, indices, peaks = cbed_frame(*shape, zero, a, b, indices, radius) template = m.radial_gradient(centerX=radius + 1, centerY=radius + 1, imageSizeX=2 * radius + 2, imageSizeY=2 * radius + 2, radius=radius) match_patterns = [ common.patterns.RadialGradient(radius=radius, search=radius * 1.5), common.patterns.BackgroundSubtraction(radius=radius, radius_outer=radius * 1.5, search=radius * 1.8), common.patterns.RadialGradientBackgroundSubtraction( radius=radius, radius_outer=radius * 1.5, search=radius * 1.8), common.patterns.UserTemplate(template=template, search=radius * 1.5) ] print("zero: ", zero) print("a: ", a) print("b: ", b) for match_pattern in match_patterns: print("refining using template %s" % type(match_pattern)) (centers, refineds, heights, elevations) = common.correlation.process_frames_full( pattern=match_pattern, frames=data, peaks=peaks.astype(np.int32), ) print(peaks - refineds) assert np.allclose(refineds[0], peaks, atol=0.5)
def test_run_refine_blocktests(lt_ctx, cls): shape = np.array([128, 128]) zero = shape / 2 a = np.array([27.17, 0.]) b = np.array([0., 29.19]) indices = np.mgrid[-2:3, -2:3] indices = np.concatenate(indices.T) radius = 7 match_pattern = common.patterns.RadialGradient(radius=radius) crop_size = match_pattern.get_crop_size() data, indices, peaks = cbed_frame(*shape, zero=zero, a=a, b=b, indices=indices, radius=radius, margin=crop_size) dataset = MemoryDataSet(data=data, tileshape=(1, *shape), num_partitions=1, sig_dims=2) # The crop buffer is float32 # FIXME adapt as soon as UDFs have dtype support nbytes = (2 * crop_size)**2 * np.dtype(np.float32).itemsize for limit in (1, nbytes - 1, nbytes, nbytes + 1, (len(peaks) - 1) * nbytes - 1, (len(peaks) - 1) * nbytes, (len(peaks) - 1) * nbytes + 1, len(peaks) * nbytes - 1, len(peaks) * nbytes, len(peaks) * nbytes + 1, *np.random.randint( low=1, high=len(peaks) * nbytes + 3, size=5)): m_udf = cls(peaks=peaks, match_pattern=match_pattern, __limit=limit) res = lt_ctx.run_udf(udf=m_udf, dataset=dataset) print(limit) print(res['refineds'].data[0]) print(peaks) print(peaks - res['refineds'].data[0]) assert np.allclose(res['refineds'].data[0], peaks, atol=0.5)
def test_run_refine_affinematch(lt_ctx): shape = np.array([256, 256]) zero = shape / 2 + np.random.uniform(-1, 1, size=2) a = np.array([27.17, 0.]) + np.random.uniform(-1, 1, size=2) b = np.array([0., 29.19]) + np.random.uniform(-1, 1, size=2) indices = np.mgrid[-3:4, -3:4] indices = np.concatenate(indices.T) radius = 10 data, indices, peaks = cbed_frame(*shape, zero, a, b, indices, radius) dataset = MemoryDataSet(data=data, tileshape=(1, *shape), num_partitions=1, sig_dims=2) matcher = grm.Matcher() match_pattern = blobfinder.RadialGradient(radius=radius) affine_indices = peaks - zero print("zero: ", zero) print("a: ", a) print("b: ", b) (res, real_indices) = blobfinder.run_refine( ctx=lt_ctx, dataset=dataset, zero=zero + np.random.uniform(-1, 1, size=2), a=np.array([1, 0]) + np.random.uniform(-0.05, 0.05, size=2), b=np.array([0, 1]) + np.random.uniform(-0.05, 0.05, size=2), indices=affine_indices, matcher=matcher, match_pattern=match_pattern, match='affine') assert np.allclose(res['zero'].data[0], zero, atol=0.5) assert np.allclose(res['a'].data[0], [1, 0], atol=0.05) assert np.allclose(res['b'].data[0], [0, 1], atol=0.05)
def test_symmetries(lt_ctx, TYPE): (d1, i1, p1) = cbed_frame(all_equal=True, radius=3, indices=np.array([(1, 0)])) (d2, i2, p2) = cbed_frame(all_equal=True, radius=3, indices=np.array([(-1, 0)])) (d3, i3, p3) = cbed_frame(all_equal=True, radius=3, indices=np.array([(1, 0), (-1, 0)])) (d4, i4, p4) = cbed_frame(all_equal=True, radius=3, indices=np.array([(1, 0), (-1, 0), (0, 1), (0, -1)])) data = np.zeros((2, 2, *d1[0].shape)) data[0, 0] = d1[0] data[0, 1] = d2[0] data[1, 0] = d3[0] data[1, 1] = d4[0] ds = MemoryDataSet(data=data) r = np.linalg.norm(p2[0] - p1[0]) / 2 cy, cx = (p2[0] + p1[0]) / 2 analysis = lt_ctx.create_radial_fourier_analysis(dataset=ds, cy=cy, cx=cx, ri=0, ro=r + 4, n_bins=2, max_order=8) analysis.TYPE = TYPE results = lt_ctx.run(analysis) c_0_0 = results.complex_0_0.raw_data c_1_0 = results.complex_1_0.raw_data assert np.allclose(np.abs(c_0_0), 0) assert np.allclose(np.abs(c_1_0), data.sum(axis=(2, 3))) c_0_1 = results.complex_0_1.raw_data c_1_1 = results.complex_1_1.raw_data assert np.allclose(np.abs(c_0_1), 0) assert np.allclose(np.abs(c_1_1[1, 0]), 0) assert np.allclose(np.abs(c_1_1[1, 1]), 0) assert np.all(np.abs(c_1_1[0, 0]) > 0) assert np.all(np.abs(c_1_1[0, 1]) > 0) assert np.allclose(np.angle(c_1_1[0, 0]), np.pi / 2) assert np.allclose(np.angle(c_1_1[0, 1]), -np.pi / 2) c_0_2 = results.complex_0_2.raw_data c_1_2 = results.complex_1_2.raw_data assert np.allclose(np.abs(c_0_2), 0) # 2-fold suppressed for 4-fold symmetry assert np.allclose(np.abs(c_1_2[1, 1]), 0) assert np.all(np.abs(c_1_2[0, 0]) > 0) assert np.all(np.abs(c_1_2[0, 1]) > 0) assert np.all(np.abs(c_1_2[1, 0]) > 0) # Discontinuity at this point, can be pi or -pi assert np.allclose(np.abs(np.angle(c_1_2[0, 0])), np.pi) assert np.allclose(np.abs(np.angle(c_1_2[0, 1])), np.pi) assert np.allclose(np.abs(np.angle(c_1_2[1, 0])), np.pi) c_0_3 = results.complex_0_3.raw_data c_1_3 = results.complex_1_3.raw_data assert np.allclose(np.abs(c_0_3), 0) # odd harmonics suppressed in 2-fold symmetry assert np.allclose(np.abs(c_1_3[1]), 0) assert np.all(np.abs(c_1_3[0, 0]) > 0) assert np.all(np.abs(c_1_3[0, 1]) > 0) assert np.allclose(np.angle(c_1_3[0, 0]), -np.pi / 2) assert np.allclose(np.angle(c_1_3[0, 1]), np.pi / 2) c_0_4 = results.complex_0_4.raw_data c_1_4 = results.complex_1_4.raw_data assert np.allclose(np.abs(c_0_4), 0) assert np.all(np.abs(c_1_4) > 0) assert np.allclose(np.angle(c_1_4[0, 0]), 0) assert np.allclose(np.angle(c_1_4[0, 1]), 0) assert np.allclose(np.angle(c_1_4[1, 0]), 0) assert np.allclose(np.angle(c_1_4[1, 1]), 0) c_0_5 = results.complex_0_5.raw_data c_1_5 = results.complex_1_5.raw_data assert np.allclose(np.abs(c_0_5), 0) # odd harmonics suppressed in 2-fold symmetry assert np.allclose(np.abs(c_1_5[1]), 0) c_0_7 = results.complex_0_5.raw_data c_1_7 = results.complex_1_5.raw_data assert np.allclose(np.abs(c_0_7), 0) # odd harmonics suppressed in 2-fold symmetry assert np.allclose(np.abs(c_1_7[1]), 0) c_0_8 = results.complex_0_4.raw_data c_1_8 = results.complex_1_4.raw_data assert np.allclose(np.abs(c_0_8), 0) assert np.all(np.abs(c_1_8) > 0) assert np.allclose(np.angle(c_1_8[0, 0]), 0) assert np.allclose(np.angle(c_1_8[0, 1]), 0) assert np.allclose(np.angle(c_1_8[1, 0]), 0) assert np.allclose(np.angle(c_1_8[1, 1]), 0)