def test_to_and_from_ascii(self, sans_benchmark): sans_prop_ref = ps.SansProperty() sans_prop_ref.from_cryson_int(sans_benchmark['cryson_int']) sans_prop = ps.SansProperty() with tempfile.NamedTemporaryFile() as f: sans_prop_ref.to_ascii(f.name) sans_prop.from_ascii(f.name) np.testing.assert_array_almost_equal( sans_prop.qvalues, sans_prop_ref.qvalues)
def test_from_cryson_pdb(self, sans_benchmark): sans_prop = ps.SansProperty() sans_prop.from_cryson_pdb(sans_benchmark['cryson_pdb'], args='') sans_prop_ref = ps.SansProperty() sans_prop_ref.from_cryson_int(sans_benchmark['cryson_int']) np.testing.assert_array_almost_equal( sans_prop.qvalues, sans_prop_ref.qvalues) np.testing.assert_array_almost_equal( sans_prop.profile, sans_prop_ref.profile)
def sans_benchmark(request): r"""Sassena output containing 1000 I(Q) profiles for the hiAPP centroids. Yields ------ dict 'profiles' : HDF5 handle to the file containing the I(Q) profiles 'property_list' : list of SansProperty instances, one for each leaf 'tree_with_no_property' : cnextend.Tree with random distances among leafs and without included properties. """ # setup or initialization handle = h5py.File(os.path.join(data_dir, 'sans', 'profiles.h5'), 'r') profiles = handle['fqt'] n_leafs = len(profiles) # Create a node tree. # m is a 1D compressed matrix of distances between leafs m = np.random.random(int(n_leafs * (n_leafs - 1) / 2)) z = linkage(m) tree = cnextend.Tree(z) # values is a list of SansProperty instances, one for each tree leaf values = list() for i in range(tree.nleafs): sans_property = idprop.SansProperty() sans_property.from_sassena(handle, index=i) values.append(sans_property) def teardown(): handle.close() request.addfinalizer(teardown) return dict(profiles=handle, property_list=values, tree_with_no_property=tree)
def sans_fit(sans_benchmark): r""" Parameters ---------- sans_benchmark : :function:`~pytest.fixture` Returns ------- dict A dictionary containing the following key, value pairs: tree: :class:`~idpflex.cnextend.Tree` A hiearchical tree with random distances among leafs, and endowed with a :class:`~idpflex.properties.SansProperty`. property_name: str Just the name of the property depth: int Tree depth resulting in the best fit to experiment_property coefficients: :py:`dict` weights of each node at Tree depth resulting in best fit. (key, val) pair is (node ID, weight). background : float Flat background added to the profile at depth for optimal fit experiment_property: :class:`~idpflex.properties.SansProperty` Experimental profile from a linear combination of the profiles at depth for optimal fit using `coefficients` and `background`. """ tree = deepcopy(sans_benchmark['tree_with_no_property']) values = sans_benchmark['property_list'] name = values[0].name # property name idprop.propagator_size_weighted_sum(values, tree) # create a SANS profile as a linear combination of the clusters at a # particular depth depth = 4 coeffs = (0.45, 0.00, 0.07, 0.25, 0.23) # they must add to one coefficients = dict() nodes = tree.nodes_at_depth(depth) n_nodes = 1 + depth # depth=0 corresponds to the root node (nclusters=1) q_values = (tree.root[name].x[:-1] + tree.root[name].x[1:]) / 2 # midpoint profile = np.zeros(len(q_values)) for i in range(n_nodes): coefficients[nodes[i].id] = coeffs[i] p = nodes[i][name] profile += coeffs[i] * (p.y[:-1] + p.y[1:]) / 2 background = 0.05 * max(profile) # flat background profile += background experiment_property = idprop.SansProperty(name=name, qvalues=q_values, profile=profile, errors=0.1 * profile) return { 'tree': tree, 'property_name': name, 'depth': depth, 'coefficients': coefficients, 'background': background, 'experiment_property': experiment_property }
def test_from_sassena(self, sans_benchmark): sans_prop = ps.SansProperty() sans_prop.from_sassena(sans_benchmark['profiles'], index=666) assert sans_prop.qvalues[13].item() - 0.0656565651298 < 0.000000001 assert sans_prop.profile[13].item() - 741970.84461578 < 0.000001
def test_default_name(self): sans_prop = ps.SansProperty() assert sans_prop.name == 'sans'
def test_from_cryson_int(self, sans_benchmark): sans_prop = ps.SansProperty() sans_prop.from_cryson_int(sans_benchmark['cryson_int']) assert sans_prop.qvalues[8] == 0.08 assert sans_prop.profile[8] == 0.229457E+06 assert sans_prop.errors[8] == 0.0