def test_find_spacegroup(self): self.assertEqual(gemmi.SpaceGroup('P21212').hm, 'P 21 21 2') self.assertEqual(gemmi.find_spacegroup_by_name('P21').hm, 'P 1 21 1') self.assertEqual(gemmi.find_spacegroup_by_name('P 2').hm, 'P 1 2 1') def check_xhm(name, xhm): self.assertEqual(gemmi.SpaceGroup(name).xhm(), xhm) check_xhm('R 3 2', 'R 3 2:H') check_xhm('R 3 2:h', 'R 3 2:H') check_xhm('R32:H', 'R 3 2:H') check_xhm('H32', 'R 3 2:H') check_xhm('R 3 2:R', 'R 3 2:R') check_xhm('P6', 'P 6') check_xhm('P 6', 'P 6') check_xhm('P65', 'P 65') check_xhm('I1211', 'I 1 21 1') check_xhm('Aem2', 'A b m 2') check_xhm('C c c e', 'C c c a:1') check_xhm('i2', 'I 1 2 1') check_xhm('I 41/A', 'I 41/a:1') check_xhm('I -4 2 D', 'I -4 2 d') check_xhm('P 1 21/c 1', 'P 1 21/c 1') check_xhm('P 21 21 2 A', 'P 21212(a)') check_xhm('B 2', 'B 1 1 2') self.assertRaises(ValueError, gemmi.SpaceGroup, 'i3') self.assertEqual(gemmi.find_spacegroup_by_number(5).hm, 'C 1 2 1') self.assertEqual(gemmi.SpaceGroup(4005).hm, 'I 1 2 1') self.assertIsNone(gemmi.find_spacegroup_by_name('abc'))
def main(): config = Config.from_config() m = gemmi.read_ccp4_map(str(config.xmap_in)) print(dir(m)) # m.spacegroup = gemmi.find_spacegroup_by_name('P1') print(m.grid.spacegroup) m.grid.spacegroup = gemmi.find_spacegroup_by_name('P1') print(m.grid.spacegroup) m.setup() print(m.grid.spacegroup) m.grid.spacegroup = gemmi.find_spacegroup_by_name('P1') print(m.grid.spacegroup) sf = gemmi.transform_map_to_f_phi(m.grid, half_l=True) print(sf.spacegroup) # data = sf print(dir(sf)) data = sf.prepare_asu_data(dmin=config.resolution, with_000=True) mtz = gemmi.Mtz(with_base=True) # mtz = gemmi.Mtz() print(dir(mtz)) mtz.spacegroup = sf.spacegroup # mtz.spacegroup = gemmi.find_spacegroup_by_name('P1') # mtz.set_cell_for_all(sf.unit_cell) mtz.cell = sf.unit_cell mtz.add_dataset('unknown') mtz.add_column('FWT', 'F') mtz.add_column('PHWT', 'P') mtz.set_data(data) mtz.write_to_file(str(config.mtz_out))
def change_basis(self, name_a, name_b, basisop_triplet): basisop = gemmi.Op(basisop_triplet) a = gemmi.find_spacegroup_by_name(name_a) b = gemmi.find_spacegroup_by_name(name_b) ops = a.operations() ops.change_basis(basisop) self.assertEqual(ops, b.operations()) ops.change_basis(basisop.inverse()) self.assertEqual(ops, a.operations())
def get_ccp4_map(xmap_path): m = gemmi.read_ccp4_map(str(xmap_path)) m.grid.spacegroup = gemmi.find_spacegroup_by_name("P 1") m.setup() return m
def get_rscc(_reference_grid, _grid, reference_structure): mask = gemmi.FloatGrid(_reference_grid.nu, _reference_grid.nv, _reference_grid.nw, ) mask.set_unit_cell(_reference_grid.unit_cell) mask.spacegroup = gemmi.find_spacegroup_by_name("P 1") for model in reference_structure: for chain in model: for residue in chain.get_polymer(): for atom in residue: mask.set_points_around(atom.pos, 3.0, 1.0) _reference_sample = np.array(_reference_grid, copy=False) _sample = np.array(_grid, copy=False) _mask = np.array(mask, copy=False) reference_flattened = _reference_sample[_mask!= 0] sample_flattened = _sample[_mask!=0] reference_sample_mean = np.mean(reference_flattened) reference_sample_demeaned = reference_flattened - reference_sample_mean reference_sample_denominator = np.sqrt(np.sum(np.square(reference_sample_demeaned))) sample_mean = np.mean(sample_flattened) sample_demeaned = sample_flattened - sample_mean sample_denominator = np.sqrt(np.sum(np.square(sample_demeaned))) nominator = np.sum(reference_sample_demeaned * sample_demeaned) denominator = sample_denominator * reference_sample_denominator correlation = nominator / denominator return correlation
def test_new(self): N = 24 m = gemmi.FloatGrid(N, N, N) self.assertEqual(m.nu, N) self.assertEqual(m.nv, N) self.assertEqual(m.nw, N) m.set_value(1, 2, 3, 1.0) self.assertEqual(sum(m), 1.0) m.space_group = gemmi.find_spacegroup_by_name('C2') self.assertEqual(m.space_group.number, 5) m.symmetrize_max() self.assertEqual(sum(m), 4.0) m.fill(2.0) m.space_group = gemmi.find_spacegroup_by_name('P 62 2 2') self.assertEqual(len(m.space_group.operations()), 12) m.set_value(1, 2, 3, 0.0) m.symmetrize_min() self.assertEqual(sum(m), 2 * N * N * N - 2 * 12)
def symmops_from_spgr(self) -> List[str]: # _symmetry_space_group_name_Hall space_group = None if self['_space_group_name_H-M_alt']: space_group = self['_space_group_name_H-M_alt'] if self['_symmetry_space_group_name_H-M']: space_group = self['_symmetry_space_group_name_H-M'] if not space_group: return [] ops = [op.triplet() for op in gemmi.find_spacegroup_by_name(gemmi.cif.as_string(space_group)).operations()] return ops
def test_phase_shift(self): ops = gemmi.find_spacegroup_by_name('P 31 2 1').operations() refl = [3, 0, 1] expected_equiv = [ # in the paper the last two reflections are swapped [3, 0, 1], [0, -3, 1], [-3, 3, 1], [0, 3, -1], [3, -3, -1], [-3, 0, -1]] self.assertEqual([op.apply_to_hkl(refl) for op in ops], expected_equiv) expected_shifts = [0, -120, -240, 0, -240, -120] for op, expected in zip(ops, expected_shifts): shift = math.degrees(op.phase_shift(refl)) self.assertAlmostEqual((shift - expected) % 360, 0)
def save_xmap( event_map, path, ): ccp4 = gemmi.Ccp4Map() ccp4.grid = event_map ccp4.grid.spacegroup = gemmi.find_spacegroup_by_name("P 1") ccp4.update_ccp4_header(2, True) ccp4.write_ccp4_map(str(path)) return path
def get_masked_sample(_reference_grid, _grid, _reference_structure): mask = gemmi.FloatGrid(_reference_grid.nu, _reference_grid.nv, _reference_grid.nw, ) mask.set_unit_cell(_reference_grid.unit_cell) mask.spacegroup = gemmi.find_spacegroup_by_name("P 1") for model in _reference_structure: for chain in model: for residue in chain.get_polymer(): for atom in residue: mask.set_points_around(atom.pos, 3.0, 1.0) _reference_sample = np.array(_reference_grid, copy=False) _sample = np.array(_grid, copy=False) _mask = np.array(mask, copy=False) sample_flattened = _sample[_mask != 0] return sample_flattened
def get_cut_out_event_map(event_map: gemmi.FloatGrid, coord: Coord, radius: float = 10.0) -> gemmi.FloatGrid: event_centroid = gemmi.Position(coord.x, coord.y, coord.z) xmap_array = np.array(event_map, copy=True) mask_grid = gemmi.Int8Grid(*xmap_array.shape) # print(f"Spacegroup: {mask_grid.spacegroup.xhm()}") # mask_grid.spacegroup = gemmi.find_spacegroup_by_name("P 21 21 21") # gemmi.find_spacegroup_by_name("P 1")#event_map.spacegroup mask_grid.spacegroup = gemmi.find_spacegroup_by_name( "P 1") #event_map.spacegroup print(f"Spacegroup: {mask_grid.spacegroup.xhm()}") print(f"grid: {mask_grid}") mask_grid_array = np.array(mask_grid) print(f"Mask grid array: {mask_grid_array.shape}") print(f"Mask grid array: {mask_grid_array.size}") print(f"Mask grid array: {np.sum(np.isfinite(mask_grid_array))}") # print(f"Grid size: {mask_grid.size}") mask_grid.set_unit_cell(event_map.unit_cell) mask_grid.set_points_around( event_centroid, radius=radius, value=1, ) mask_grid.symmetrize_max() mask_array = np.array(mask_grid, copy=False, dtype=np.int8) new_grid = gemmi.FloatGrid(*xmap_array.shape) new_grid.spacegroup = event_map.spacegroup # gemmi.find_spacegroup_by_name("P 1") new_grid.set_unit_cell(event_map.unit_cell) new_grid_array = np.array(new_grid, copy=False) new_grid_array[np.nonzero(mask_array)] = xmap_array[np.nonzero(mask_array)] new_grid.symmetrize_max() return new_grid
def score_structure(structure, xmap): unit_cell = xmap.unit_cell mask = gemmi.FloatGrid(xmap.nu, xmap.nv, xmap.nw) mask.set_unit_cell(unit_cell) mask.spacegroup = gemmi.find_spacegroup_by_name("P 1") for model in structure: for chain in model: for residue in chain: for atom_1 in residue: if atom_1.element.name == "H": continue pos_1 = atom_1.pos for atom_2 in residue: if atom_2.element.name == "H": continue pos_2 = atom_2.pos if pos_1.dist(pos_2) < 2.0: new_pos = gemmi.Position( (pos_1.x + pos_2.x) / 2, (pos_1.y + pos_2.y) / 2, (pos_1.z + pos_2.z) / 2, ) mask.set_points_around(new_pos, 0.75, 1.0) mask_array = np.array(mask) xmap_array = np.array(xmap) truncated_xmap_mask = xmap_array > 1.25 score = np.sum(truncated_xmap_mask * mask_array) return float(score)
def get_mask(dataset: Dataset, alignment, sample_region, structure_factors, sample_rate, ): # Get the unaligned xmap reflections: gemmi.Mtz = dataset.reflections unaligned_xmap: gemmi.FloatGrid = reflections.transform_f_phi_to_map( structure_factors.f, structure_factors.phi, sample_rate=sample_rate, ) unaligned_xmap_array = np.array(unaligned_xmap, copy=False) std = np.std(unaligned_xmap_array) unaligned_xmap_array[:, :, :] = unaligned_xmap_array[:, :, :] / std # Transform sample region transformed_sample_region = get_transformed_sample_region( sample_region, alignment, ) # mask mask = gemmi.FloatGrid(unaligned_xmap.nu, unaligned_xmap.nv, unaligned_xmap.nw, ) mask.set_unit_cell(unaligned_xmap.unit_cell) mask.spacegroup = gemmi.find_spacegroup_by_name("P 1") for model in dataset.structure: for chain in model: for residue in chain.get_polymer(): for atom in residue: mask.set_points_around(atom.pos, 3.0, 1.0) # Get sample # reference_sample = sample_dataset_global(mask, transformed_sample_region) return mask
def get_event_map(event_map_file: Path) -> gemmi.FloatGrid: m = gemmi.read_ccp4_map(str(event_map_file)) print(m.grid.spacegroup.xhm()) # m.grid.spacegroup = gemmi.find_spacegroup_by_name("P 21 21 21") m.grid.spacegroup = gemmi.find_spacegroup_by_name("P 1") print(m.grid.spacegroup.xhm()) m.setup() grid_array = np.array(m.grid, copy=True) print(m.grid.spacegroup.xhm()) print(m.grid) print(grid_array.shape) new_grid = gemmi.FloatGrid(*grid_array.shape) new_grid.spacegroup = m.grid.spacegroup # gemmi.find_spacegroup_by_name("P 1") new_grid.set_unit_cell(m.grid.unit_cell) new_grid_array = np.array(new_grid, copy=False) new_grid_array[:, :, :] = grid_array[:, :, :] return new_grid
def to_gemmi(self): return gemmi.find_spacegroup_by_name(self.spacegroup)
def resample( reference_xmap: gemmi.FloatGrid, moving_xmap: gemmi.FloatGrid, reference_structure: gemmi.Structure, moving_structure: gemmi.Structure, monomerized=False, ): # Get transform: from ref to align transform = get_alignment(moving_structure, reference_structure, monomerized=monomerized) print(f"Transform: {transform}; {transform.transform.vec} {transform.transform.mat}") interpolated_grid = gemmi.FloatGrid( reference_xmap.nu, reference_xmap.nv, reference_xmap.nw, ) interpolated_grid.set_unit_cell(reference_xmap.unit_cell) interpolated_grid.spacegroup = reference_xmap.spacegroup # points mask = gemmi.FloatGrid(reference_xmap.nu, reference_xmap.nv, reference_xmap.nw, ) mask.set_unit_cell(reference_xmap.unit_cell) mask.spacegroup = gemmi.find_spacegroup_by_name("P 1") for model in reference_structure: for chain in model: for residue in chain.get_polymer(): for atom in residue: mask.set_points_around(atom.pos, 3.0, 1.0) mask_array = np.array(mask) mask_indicies = np.hstack([x.reshape((len(x), 1)) for x in np.nonzero(mask)]) print(f"Mask indicies shape: {mask_indicies.shape}") fractional_coords = [] for model in reference_structure: for chain in model: for residue in chain.get_polymer(): for atom in residue: fractional = reference_xmap.unit_cell.fractionalize(atom.pos) fractional_coords.append([fractional.x, fractional.y, fractional.z]) fractional_coords_array = np.array(fractional_coords) max_coord = np.max(fractional_coords_array, axis=0) min_coord = np.min(fractional_coords_array, axis=0) min_index = np.floor(min_coord * np.array([interpolated_grid.nu, interpolated_grid.nv, interpolated_grid.nw])) max_index = np.floor(max_coord * np.array([interpolated_grid.nu, interpolated_grid.nv, interpolated_grid.nw])) points = itertools.product(range(int(min_index[0]), int(max_index[0])), range(int(min_index[1]), int(max_index[1])), range(int(min_index[2]), int(max_index[2])), ) # Unpack the points, poitions and transforms point_list: List[Tuple[int, int, int]] = [] position_list: List[Tuple[float, float, float]] = [] transform_list: List[gemmi.transform] = [] com_moving_list: List[np.array] = [] com_reference_list: List[np.array] = [] transform_rotate_reference_to_moving = transform.transform transform_rotate_reference_to_moving.vec.fromlist([0.0, 0.0, 0.0]) transform_reference_to_centered = gemmi.Transform() transform_reference_to_centered.vec.fromlist((-transform.com_reference).tolist()) transform_reference_to_centered.mat.fromlist(np.eye(3).tolist()) tranform_centered_to_moving = gemmi.Transform() tranform_centered_to_moving.vec.fromlist(transform.com_moving.tolist()) tranform_centered_to_moving.mat.fromlist(np.eye(3).tolist()) # indicies to positions for point in points: if mask.get_value(*point) < 1.0: continue # get position position = interpolated_grid.get_position(*point) # Tranform to origin frame position_origin_reference = gemmi.Position(transform_reference_to_centered.apply(position)) # Rotate position_origin_moving = gemmi.Position(transform_rotate_reference_to_moving.apply(position_origin_reference)) # Transform to moving frame position_moving = gemmi.Position(tranform_centered_to_moving.apply(position_origin_moving)) # Interpolate moving map interpolated_map_value = moving_xmap.interpolate_value(position_moving) # Set original point interpolated_grid.set_value(point[0], point[1], point[2], interpolated_map_value) interpolated_grid.symmetrize_max() return interpolated_grid
def get_structure(name, page, result_url): # initializing entries = [] str1s = [] # Condition strings str2s = [] # Syngonia strings # test if structure data exists exist = page.find('Кристаллографические данные') if exist != -1: acquire = True pos = exist else: acquire = False # get all structure data using the while-loop while acquire == True: # Condition pos = page.find('title="Библиография">', pos) str1pos = pos + 21 str1pos_end = page.find('<', pos) str1 = page[str1pos:str1pos_end] # Syngonia pos = page.find('title="Библиография">', pos + 21) str2pos = pos + 21 str2pos_end = page.find('<', pos) str2 = page[str2pos:str2pos_end] # Symmetry class symmetry_start = page.find('title="Библиография">', pos + 21) + 21 symmetry_end = page.find('</a></td>', symmetry_start) symmetry = page[symmetry_start:symmetry_end] symmetry = str_structure(symmetry) # Spacegroup spacegroup_start = page.find('title="Библиография">', symmetry_end) + 21 spacegroup_end = page.find('</a></td>', spacegroup_start) spacegroup = page[spacegroup_start:spacegroup_end] spacegroup = str_structure(spacegroup) # try placing - at different locations sg1 = spacegroup sg2 = spacegroup[:1] + '-' + spacegroup[1:] sg3 = spacegroup[:2] + '-' + spacegroup[2:] sg = {sg1, sg2, sg3} # find spacegroup number by name for sg_str in sg: valid = True try: spacegroup_number = gemmi.find_spacegroup_by_name(sg_str) spacegroup_number = spacegroup_number.number if spacegroup_number is None: raise Exception except: valid = False if valid == True: spacegroup = sg_str break # corresponding crystal system crystal_system = sgn2system(spacegroup_number) # end position in page pos = page.find('title="Библиография">', spacegroup_end) pos = page.find('</a></td>', pos) # find normalized unit cell volume using Materials Project normalized_volume = 'NaN' ref_vol = 'N/A' # reference link to the volume data mp_data = mp.single_query(name) for each in mp_data: if each != []: if each[1] == spacegroup_number: normalized_volume = each[2] ref_vol = each[3] # organize all data into entries entry = [ name, symmetry, spacegroup, spacegroup_number, crystal_system, normalized_volume, result_url, ref_vol ] entries.append(entry) str1s.append(str1) str2s.append(str2) # test if there is more data test_str = page[pos + 16:pos + 24] if test_str == '</table>': acquire = False else: acquire = True return entries, str1s, str2s
space_groups_txt = sys.argv[1] chunks = open(space_groups_txt).read().split('\n\n') def parse_chunk(lines): return { 'number': int(lines[0]), 'hall': lines[1].strip(), 'xhm': lines[2].strip(), 'symops': [gemmi.Op(line) for line in lines[3:]] } data = [parse_chunk(c.splitlines()) for c in chunks if c] print(len(data), 'items') for d in data: ops = gemmi.symops_from_hall(d['hall']) assert len(ops.sym_ops) * len(ops.cen_ops) == len(d['symops']) given = set(d['symops']) generated = set(ops) if given != generated: print(d['hall']) print('common:', ' '.join(x.triplet() for x in given & generated)) print('given: ', ' '.join(x.triplet() for x in given - generated)) print('generated:', ' '.join(x.triplet() for x in generated - given)) for d in data: names = d['xhm'].split(',') if all(gemmi.find_spacegroup_by_name(name) is None for name in names): print('not in gemmi:', names)