def test_init(self): # test init with the following space group: # 71.538 (BNS number), I_cmmm (BNS label) # 65.10.554 (same space group as above, OG number), C_Immm (OG label) msg_from_bns_1 = MagneticSpaceGroup("I_cmmm") msg_from_bns_2 = MagneticSpaceGroup([71, 538]) msg_from_og_1 = MagneticSpaceGroup.from_og("C_Immm") msg_from_og_2 = MagneticSpaceGroup.from_og([65, 10, 554]) self.assertEqual(msg_from_bns_1, msg_from_bns_2) self.assertEqual(msg_from_og_1, msg_from_og_2) self.assertEqual(msg_from_bns_1, msg_from_og_1)
def test_equivalence_to_spacegroup(self): # first 230 magnetic space groups have same symmetry operations # as normal space groups, so should give same orbits labels = ["Fm-3m", "Pnma", "P2/c", "P-1"] points = [[0, 0, 0], [0.5, 0, 0], [0.11, 0.22, 0.33]] for label in labels: sg = SpaceGroup(label) msg = MagneticSpaceGroup(label) self.assertEqual(sg.crystal_system, msg.crystal_system) for p in points: pp_sg = np.array(sg.get_orbit(p)) pp_msg = np.array(msg.get_orbit(p, 0)[0]) # discarding magnetic moment information pp_sg = pp_sg[np.lexsort(np.transpose(pp_sg)[::-1])] # sorting arrays so we can compare them pp_msg = pp_msg[np.lexsort(np.transpose(pp_msg)[::-1])] self.assertTrue(np.allclose(pp_sg, pp_msg))
def test_str(self): msg = MagneticSpaceGroup([4, 11]) ref_string = """BNS: 4.11 P_b2_1 Operators: (1|0,0,0) (2y|0,1/2,0) (1|0,1/2,0)' (2y|0,0,0)' Wyckoff Positions: 4e (x,y,z;mx,my,mz) (-x,y+1/2,-z;-mx,my,-mz) (x,y+1/2,z;-mx,-my,-mz) (-x,y,-z;mx,-my,mz) 2d (1/2,y,1/2;mx,0,mz) (1/2,y+1/2,1/2;-mx,0,-mz) 2c (1/2,y,0;mx,0,mz) (1/2,y+1/2,0;-mx,0,-mz) 2b (0,y,1/2;mx,0,mz) (0,y+1/2,1/2;-mx,0,-mz) 2a (0,y,0;mx,0,mz) (0,y+1/2,0;-mx,0,-mz) Alternative OG setting exists for this space group.""" ref_string_all = """BNS: 4.11 P_b2_1 OG: 3.7.14 P_2b2' OG-BNS Transform: (a,2b,c;0,0,0) Operators (BNS): (1|0,0,0) (2y|0,1/2,0) (1|0,1/2,0)' (2y|0,0,0)' Wyckoff Positions (BNS): 4e (x,y,z;mx,my,mz) (-x,y+1/2,-z;-mx,my,-mz) (x,y+1/2,z;-mx,-my,-mz) (-x,y,-z;mx,-my,mz) 2d (1/2,y,1/2;mx,0,mz) (1/2,y+1/2,1/2;-mx,0,-mz) 2c (1/2,y,0;mx,0,mz) (1/2,y+1/2,0;-mx,0,-mz) 2b (0,y,1/2;mx,0,mz) (0,y+1/2,1/2;-mx,0,-mz) 2a (0,y,0;mx,0,mz) (0,y+1/2,0;-mx,0,-mz) Operators (OG): (1|0,0,0) (2y|0,1,0) (1|0,1,0)' (2y|0,0,0)' Wyckoff Positions (OG): (1,0,0)+ (0,2,0)+ (0,0,1)+ 4e (x,y,z;mx,my,mz) (-x,y+1,-z;-mx,my,-mz) (x,y+1,z;-mx,-my,-mz) (-x,y,-z;mx,-my,mz) 2d (1/2,y,1/2;mx,0,mz) (-1/2,y+1,-1/2;-mx,0,-mz) 2c (1/2,y,0;mx,0,mz) (-1/2,y+1,0;-mx,0,-mz) 2b (0,y,1/2;mx,0,mz) (0,y+1,-1/2;-mx,0,-mz) 2a (0,y,0;mx,0,mz) (0,y+1,0;-mx,0,-mz)""" self.assertStrContentEqual(str(msg), ref_string) self.assertStrContentEqual(msg.data_str(), ref_string_all)
def get_magsymops(self, data): """ Equivalent to get_symops except for magnetic symmetry groups. Separate function since additional operation for time reversal symmetry (which changes magnetic moments on sites) needs to be returned. """ magsymmops = [] # check to see if magCIF file explicitly contains magnetic symmetry operations if data.data.get("_space_group_symop_magn_operation.xyz"): xyzt = data.data.get("_space_group_symop_magn_operation.xyz") if isinstance(xyzt, six.string_types): xyzt = [xyzt] magsymmops = [MagSymmOp.from_xyzt_string(s) for s in xyzt] if data.data.get("_space_group_symop_magn_centering.xyz"): xyzt = data.data.get("_space_group_symop_magn_centering.xyz") if isinstance(xyzt, six.string_types): xyzt = [xyzt] centering_symops = [ MagSymmOp.from_xyzt_string(s) for s in xyzt ] all_ops = [] for op in magsymmops: for centering_op in centering_symops: new_translation = [ i - np.floor(i) for i in op.translation_vector + centering_op.translation_vector ] new_time_reversal = op.time_reversal * centering_op.time_reversal all_ops.append( MagSymmOp. from_rotation_and_translation_and_time_reversal( rotation_matrix=op.rotation_matrix, translation_vec=new_translation, time_reversal=new_time_reversal)) magsymmops = all_ops # else check to see if it specifies a magnetic space group elif data.data.get("_space_group_magn.name_BNS") or data.data.get( "_space_group_magn.number_BNS"): if data.data.get("_space_group_magn.name_BNS"): # get BNS label for MagneticSpaceGroup() id = data.data.get("_space_group_magn.name_BNS") else: # get BNS number for MagneticSpaceGroup() # by converting string to list of ints id = list( map(int, (data.data.get( "_space_group_magn.number_BNS").split(".")))) msg = MagneticSpaceGroup(id) if data.data.get("_space_group_magn.transform_BNS_Pp_abc"): if data.data.get("_space_group_magn.transform_BNS_Pp_abc" ) != "a,b,c;0,0,0": return NotImplementedError( "Non-standard settings not currently supported.") elif data.data.get("_space_group_magn.transform_BNS_Pp"): return NotImplementedError( "Incomplete specification to implement.") magsymmops = msg.symmetry_ops if not magsymmops: warnings.warn( "No magnetic symmetry detected, using primitive symmetry.") magsymmops = [MagSymmOp.from_xyzt_string("x, y, z, 1")] return magsymmops
def test_is_compatible(self): cubic = Lattice.cubic(1) hexagonal = Lattice.hexagonal(1, 2) rhom = Lattice.rhombohedral(3, 80) tet = Lattice.tetragonal(1, 2) ortho = Lattice.orthorhombic(1, 2, 3) msg = MagneticSpaceGroup("Fm-3m") self.assertTrue(msg.is_compatible(cubic)) self.assertFalse(msg.is_compatible(hexagonal)) msg = MagneticSpaceGroup("Pnma") self.assertTrue(msg.is_compatible(cubic)) self.assertTrue(msg.is_compatible(tet)) self.assertTrue(msg.is_compatible(ortho)) self.assertFalse(msg.is_compatible(rhom)) self.assertFalse(msg.is_compatible(hexagonal)) msg = MagneticSpaceGroup("P2/c") self.assertTrue(msg.is_compatible(cubic)) self.assertTrue(msg.is_compatible(tet)) self.assertTrue(msg.is_compatible(ortho)) self.assertFalse(msg.is_compatible(rhom)) self.assertFalse(msg.is_compatible(hexagonal)) msg = MagneticSpaceGroup("P-1") self.assertTrue(msg.is_compatible(cubic)) self.assertTrue(msg.is_compatible(tet)) self.assertTrue(msg.is_compatible(ortho)) self.assertTrue(msg.is_compatible(rhom)) self.assertTrue(msg.is_compatible(hexagonal))
def setUp(self): self.msg_1 = MagneticSpaceGroup([70, 530]) self.msg_2 = MagneticSpaceGroup([62, 448]) self.msg_3 = MagneticSpaceGroup([20, 37]) self.msg_4 = MagneticSpaceGroup([2, 7], "c,1/4a+1/4b,-1/2a+1/2b;0,0,0")
def __init__(self, structure): """ Args: """ self.input_structure = structure.copy() iso_location = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'iso/') self.input_filename_cif = os.path.join(iso_location, 'findsym_input.mcif') self.output_filename_cif = os.path.join(iso_location, 'findsym.cif') # self.input_filename_findsym = os.path.join(iso_location, 'findsym_in.in') self.input_filename_findsym = 'findsym_in.in' self.write_cif_input() # write initial input from mcif file findsym_command = 'findsym_cifinput ' + self.input_filename_cif logger.debug("""starting isotropy session in {} using isotropy in: {}""".format( os.getcwd(), iso_location)) self.findsym_cifinput_process = Command(os.path.join( iso_location, findsym_command), stdout=Capture(buffer_size=1), env={"ISODATA": iso_location}) try: self.findsym_cifinput_process.run(input=PIPE, async_=False) except FileNotFoundError: raise Exception( "Couldn't find Isotropy (findsym) for Linux, see installation instructions" ) with open(self.input_filename_findsym, "w") as io_file: # move past initial output keep_reading = True while keep_reading: # this_line = self.iso_process.stdout.readline().decode() this_line = self.findsym_cifinput_process.stdout.readline( ).decode() if this_line: # don't log until isotropy responds logger.debug("isotropy: {}".format(this_line)) io_file.write(this_line) else: keep_reading = False # run findsym findsym_command = 'findsym ' + self.input_filename_findsym self.findsym_process = Command(os.path.join(iso_location, findsym_command), stdout=Capture(buffer_size=1), env={"ISODATA": iso_location}) try: self.findsym_process.run(input=PIPE, async_=False) except FileNotFoundError: raise Exception( "Couldn't find Isotropy (findsym) for Linux, see installation instructions" ) # # move past initial output # keep_reading = True # while keep_reading: # this_line = self.findsym_process.stdout.readline().decode() # # this_line = self.read_iso_line() # if this_line: # don't log until isotropy responds # logger.debug("isotropy: {}".format(this_line)) # else: # keep_reading = False self.output_cif_file = CifFile.from_file(self.output_filename_cif) msg_int_symbol = int(self.output_cif_file.data['findsym-output']. data['_symmetry_Int_Tables_number']) self.magnetic_space_group = MagneticSpaceGroup(msg_int_symbol)
def setUp(self): self.msg_1 = MagneticSpaceGroup([70, 530]) self.msg_2 = MagneticSpaceGroup([62, 448]) self.msg_3 = MagneticSpaceGroup([20, 37])