def main(): syminfo = parse_syminfo(sys.argv[1]) seen_nums = set() for entry in syminfo: ccp4 = entry['ccp4'] hall = entry['hall'] basisop = entry['basisop'] num = entry['number'] xhm = entry['xhm'] if num not in seen_nums: seen_nums.add(num) assert ccp4 == num if basisop != 'x,y,z': print(num, xhm, basisop) assert ccp4 == 0 or ccp4 % 1000 == num if ccp4 == num: if basisop != 'x,y,z': pass # print(ccp4, basisop) if basisop != 'x,y,z': if '(%s)' % basisop not in hall: print('Hall symbol "%s" w/o basisop: %s' % (hall, basisop)) hall_ops = gemmi.symops_from_hall(hall) assert len(hall_ops.cen_ops) == len(entry['cenops']) assert (set(gemmi.Op().translated(tr) for tr in hall_ops.cen_ops) == set(entry['cenops'])) assert len(hall_ops.sym_ops) == len(entry['symops']) # symops differ in about dozen cases but are the same modulo # centering vectors generated = set(hall_ops) given = set(s * c for s in entry['symops'] for c in entry['cenops']) assert generated == given, entry print('OK. %d entries.' % len(syminfo)) hall_ref = read_ref() xhm_set = set() for d in syminfo: xhm = d['xhm'] if xhm and xhm in xhm_set: print('dup xHM:', xhm) xhm_set.add(xhm) ref = hall_ref.get(xhm) if ref is not None: assert d['number'] == ref[0] hall1 = d['hall'] hall2 = ref[1] sym1 = gemmi.symops_from_hall(hall1) sym2 = gemmi.symops_from_hall(hall2) assert set(sym1) == set(sym2), (hall1, hall2) else: print('extra:', xhm, ' (%d)' % d['number'], d['hall']) missing = set(hall_ref.keys()) - xhm_set for d in sorted(missing, key=lambda m: hall_ref[m][0]): print('missing:', d, ' (%d)' % hall_ref[d][0])
def compare_hall_symops_with_sgtbx(self, hall, existing_group=True): cctbx_sg = sgtbx.space_group(hall) cctbx_triplets = set(m.as_xyz() for m in cctbx_sg.all_ops(mod=1)) gemmi_gops = gemmi.symops_from_hall(hall) self.assertEqual(len(gemmi_gops.sym_ops), cctbx_sg.order_p()) self.assertEqual(len(gemmi_gops.cen_ops), cctbx_sg.n_ltr()) self.assertEqual(len(gemmi_gops), cctbx_sg.order_z()) self.assertEqual(gemmi_gops.is_centric(), cctbx_sg.is_centric()) ctr = gemmi_gops.find_centering() self.assertEqual(ctr, cctbx_sg.conventional_centring_type_symbol()) gemmi_triplets = set(m.triplet() for m in gemmi_gops) self.assertEqual(cctbx_triplets, gemmi_triplets) gemmi_sg = gemmi.find_spacegroup_by_ops(gemmi_gops) if existing_group: self.assertEqual(gemmi_sg.point_group_hm(), cctbx_sg.point_group_type()) self.assertEqual(gemmi_sg.crystal_system_str(), cctbx_sg.crystal_system().lower()) self.assertEqual(gemmi_sg.is_sohncke(), cctbx_sg.is_chiral()) self.assertEqual(gemmi_sg.is_enantiomorphic(), cctbx_sg.type().is_enantiomorphic()) self.assertEqual(gemmi_sg.is_symmorphic(), cctbx_sg.type().is_symmorphic()) self.assertEqual(gemmi_sg.centring_type(), ctr) else: self.assertIsNone(gemmi_sg)
def compare_hall_symops_with_sgtbx(self, hall): cctbx_sg = sgtbx.space_group(hall) cctbx_ops = set(m.as_xyz() for m in cctbx_sg.all_ops(mod=1)) gemmi_sg = gemmi.symops_from_hall(hall) self.assertEqual(len(gemmi_sg.sym_ops), cctbx_sg.order_p()) self.assertEqual(len(gemmi_sg.cen_ops), cctbx_sg.n_ltr()) gemmi_ops = set(m.triplet() for m in gemmi_sg) self.assertEqual(cctbx_ops, gemmi_ops)
def verify_hall_symbol(entry): if not gemmi: return hall_ops = gemmi.symops_from_hall(entry['hall']) assert len(hall_ops.sym_ops) == len(entry['symops']) assert len(hall_ops.cen_ops) == len(entry['cenops']) # centering vectors are exactly the same assert (set(gemmi.Op().translated(tr) for tr in hall_ops.cen_ops) == set(gemmi.Op(e) for e in entry['cenops'])), entry # symops differ in some cases but are the same modulo centering vectors given = set(gemmi.Op(s) * c for s in entry['symops'] for c in entry['cenops']) assert given == set(hall_ops), entry
def test_operations(self): gops = gemmi.symops_from_hall('-P 2a 2ac (z,x,y)') self.assertEqual(set(gemmi.SpaceGroup('Pbaa').operations()), set(gops)) self.assertEqual(gemmi.find_spacegroup_by_ops(gops).hm, 'P b a a')
def quot(s): return '"%s"' % s.replace('"', r'\"') for s in sgtbx.space_group_symbol_iterator(): xhm = s.hermann_mauguin() ext = ' 0' if s.extension() != '\0': xhm += ':%s' % s.extension() ext = "'%c'" % s.extension() info = syminfo_dict.pop(xhm) assert info['number'] == s.number() cctbx_sg = sgtbx.space_group(s.hall()) cctbx_info = sgtbx.space_group_info(group=cctbx_sg) from_ref, basisop_idx = get_basisop(cctbx_info) assert from_ref == info['basisop'], (from_ref, info['basisop']) if gemmi: assert (set(gemmi.symops_from_hall(s.hall())) == set(gemmi.symops_from_hall(info['hall']))), xhm print(fmt % (s.number(), info['ccp4'], quot(s.hermann_mauguin()), ext, quot(s.qualifier()), quot(s.hall().strip()), basisop_idx, counter)) counter += 1 print(' // And extra entries from syminfo.lib') for info in syminfo_data: if info['xhm'] in syminfo_dict: # i.e. it was not printed yet hm = info['xhm'] if not hm: hm = info['old'][0] if hm == 'P 21 21 2 (a)': # slightly too long hm = 'P 21212(a)' ext = ' 0' if ':' in hm:
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)