@@ -686,9 +686,112 @@ def test_get_occupancies(datafile):
686686 assert numpy .allclose (actual_occupancies , expected_occupancies )
687687
688688
689- # def test_convert_ase_to_diffpy_structure(datafile):
690- # """Check convert_ase_to_diffpy_structure()"""
691- # assert False
689+ def test_get_lattice_vectors (datafile ):
690+ """Check Structure.get_lattice_vectors()"""
691+ pbte_stru = Structure (filename = datafile ("PbTe.cif" ))
692+ actual_lattice_vectors = pbte_stru .get_lattice_vectors ()
693+ expected_lattice_vectors = numpy .array ([[6.461 , 0.0 , 0.0 ], [0.0 , 6.461 , 0.0 ], [0.0 , 0.0 , 6.461 ]])
694+ assert numpy .allclose (actual_lattice_vectors , expected_lattice_vectors )
695+
696+
697+ def test_get_lattice_vector_angles (datafile ):
698+ """Check Structure.get_lattice_vector_angles()"""
699+ pbte_stru = Structure (filename = datafile ("PbTe.cif" ))
700+ actual_lattice_vector_angles = pbte_stru .get_lattice_vector_angles ()
701+ expected_lattice_vector_angles = numpy .array ([90.0 , 90.0 , 90.0 ])
702+ assert numpy .allclose (actual_lattice_vector_angles , expected_lattice_vector_angles )
703+
704+
705+ @pytest .mark .parametrize (
706+ "input" ,
707+ [
708+ # case: user calls the conversion function on a Structure object that already contains
709+ # a structure
710+ # expected: the structure is wiped clean and replaced with the converted structure
711+ # we use the fixture to create a Structure object that already contains a structure.
712+ "use_diffpy_structure_fixture" ,
713+ # case: user calls the conversion function on an empty Structure object
714+ # expected: the converted structure is added to the empty Structure object without issue
715+ Structure (),
716+ ],
717+ )
718+ def test_convert_ase_to_diffpy_structure (input , build_ase_atom_object , build_diffpy_structure_object ):
719+ """Check convert_ase_to_diffpy_structure()"""
720+ # input: User wants to convert an ASE.Atoms object to a diffpy.structure.Structure object
721+ # expected: All similar data is transferred correctly,
722+ # including chemical symbols, fractional coordinates, and lattice parameters.
723+
724+ # Create an ASE.Atoms object
725+ ase_zb = build_ase_atom_object
726+ # Create an identical expected diffpy Structure object
727+ expected_structure = build_diffpy_structure_object
728+
729+ # Create new Structure object and convert ase to diffpy structure.
730+ # Use the string input to determine which type of Structure object to create for the test
731+ if isinstance (input , str ):
732+ actual_structure = build_diffpy_structure_object
733+ else :
734+ actual_structure = input
735+ # set the lost_info variable, which gets the attribute of method from ASE.Atoms object, gets the values
736+ # and stores it in a dict. This is used because ASE.Atoms stores more/different
737+ # info that a diffpy.structure object
738+ lost_info_dict = actual_structure .convert_ase_to_diffpy_structure (ase_zb , lost_info = ["get_masses" ])
739+ actual_masses = lost_info_dict ["get_masses" ]
740+ expected_masses = ase_zb .get_masses ()
741+ assert numpy .allclose (actual_masses , expected_masses )
742+
743+ # Compare the actual and expected values
744+ expected_lattice_vectors = expected_structure .get_lattice_vectors ()
745+ actual_lattice_vectors = actual_structure .get_lattice_vectors ()
746+ assert numpy .allclose (expected_lattice_vectors , actual_lattice_vectors )
747+
748+ expected_lattice_angle = expected_structure .get_lattice_vector_angles ()
749+ actual_lattice_angle = actual_structure .get_lattice_vector_angles ()
750+ assert numpy .allclose (expected_lattice_angle , actual_lattice_angle )
751+
752+ expected_symbols = expected_structure .get_chemical_symbols ()
753+ actual_symbols = actual_structure .get_chemical_symbols ()
754+ assert actual_symbols == expected_symbols
755+
756+ expected_coords = expected_structure .get_fractional_coordinates ()
757+ actual_coords = actual_structure .get_fractional_coordinates ()
758+ assert numpy .allclose (actual_coords , expected_coords )
759+
760+
761+ def test_convert_ase_to_diffpy_structure_bad_typeerror ():
762+ """Check convert_ase_to_diffpy_structure() with bad input."""
763+ bad_input = "string" # pass a string instead of ase.Atoms
764+ expected_error_msg = "Input must be an instance of ase.Atoms but got type str."
765+ actual_structure = Structure ()
766+ with pytest .raises (TypeError , match = expected_error_msg ):
767+ actual_structure .convert_ase_to_diffpy_structure (bad_input )
768+
769+
770+ @pytest .mark .parametrize (
771+ "bad_lost_info,error,expected_error_msg" ,
772+ [ # case: User provides an ASE.Atoms object but requests lost_info that is not an attribute of ASE.Atoms
773+ # expected: A ValueError is raised with a clear error message indicating the requested lost_info
774+ # attribute is invalid.
775+ (["invalid_method" ], ValueError , "ASE.Atoms object has no attribute 'invalid_method'" ),
776+ # case: User provides an ASE.Atoms object but requests lost_info that is an attribute of ASE.Atoms
777+ # but has not been set yet.
778+ # expected: The error message from ase is raised indicating the specific issue with the
779+ # requested lost_info attribute.
780+ # We set the expected error message to None because this expectation is
781+ # out of our control, but it is good to make sure that we are
782+ # raising the error from ASE.
783+ (["get_magnetic_moments" ], RuntimeError , None ),
784+ ],
785+ )
786+ def test_convert_ase_to_diffpy_structure_bad_valueerror (
787+ bad_lost_info , error , expected_error_msg , build_ase_atom_object
788+ ):
789+ """Check convert_ase_to_diffpy_structure() with bad lost_info."""
790+ ase_zb = build_ase_atom_object
791+ actual_structure = Structure ()
792+ with pytest .raises (error , match = expected_error_msg ):
793+ actual_structure .convert_ase_to_diffpy_structure (ase_zb , lost_info = bad_lost_info )
794+
692795
693796# ----------------------------------------------------------------------------
694797
0 commit comments