Beispiel #1
0
    def create_new_object_proxy(self):
        """def on_accept(mixture_type):
            if mixture_type == "mixture":
                self.add_object(Mixture(parent=self.model))
            #elif mixture_type == "insitu":
            #    self.add_object(InSituMixture(parent=self.model))
                
        # TODO re-use this and reset the COMBO etc.
        self.add_model = Model()
        self.add_view = AddMixtureView(types_dict={
            'mixture': "Create a regular mixture", 
            #'insitu': "Create an in-situ mixture"
        }, parent=self.view)
        self.add_ctrl = AddMixtureController(
            model=self.add_model, view=self.add_view, parent=self.parent,
            callback=on_accept
        )

        self.add_view.present()"""
        return Mixture(parent=self.model)  #None
Beispiel #2
0
 def setUp(self):
     self.project = Project(name="TestProject")
     self.mixture = Mixture(name="TestMixture", parent=self.project)
Beispiel #3
0
class TestMixture(unittest.TestCase):

    atom_type = None

    def setUp(self):
        self.project = Project(name="TestProject")
        self.mixture = Mixture(name="TestMixture", parent=self.project)

    def tearDown(self):
        del self.mixture
        del self.project

    def test_not_none(self):
        self.assertIsNotNone(self.mixture)

    def test_data_object(self):
        self.assertIsNotNone(self.mixture.data_object)

    test_name = create_object_attribute_test("mixture", "name", "Test Name")

    def test_parent(self):
        parent_project = Project(name="Parent2")
        self.mixture.parent = parent_project
        self.assertEqual(self.mixture.parent, parent_project)

    def test_add_phase_slot(self):
        index = self.mixture.add_phase_slot("TestPhase", 0.5)
        self.assertEqual(index, 0, "Adding a phase slot should return the correct index!")

    def test_add_specimen_slot(self):
        index = self.mixture.add_specimen_slot(None, 1.0, 0)
        self.assertEqual(index, 0, "Adding a specimen slot should return the correct index!")

    def test_add_order1(self):
        """Test if addition works when 1st specimen slot is added before 1st phase slot"""
        self.mixture.add_specimen_slot(None, 1.0, 0)
        self.assertEqual(len(self.mixture.specimens), 1)
        self.assertEqual(len(self.mixture.phases), 0)
        self.assertEqual(len(self.mixture.fractions), 0)
        self.assertEqual(self.mixture.phase_matrix.shape, (1, 0))
        self.mixture.add_phase_slot("TestPhase", 0.5)
        self.assertEqual(len(self.mixture.specimens), 1)
        self.assertEqual(len(self.mixture.phases), 1)
        self.assertEqual(len(self.mixture.fractions), 1)
        self.assertEqual(self.mixture.phase_matrix.shape, (1, 1))
        self.assertEqual(self.mixture.phase_matrix[0, 0], None)

    def test_add_order2(self):
        """Test if addition works when 1st phase slot is added before 1st specimen slot"""
        self.mixture.add_phase_slot("TestPhase", 0.5)
        self.assertEqual(len(self.mixture.specimens), 0)
        self.assertEqual(len(self.mixture.phases), 1)
        self.assertEqual(len(self.mixture.fractions), 1)
        self.assertEqual(self.mixture.phase_matrix.shape, (0, 1))
        self.mixture.add_specimen_slot(None, 1.0, 0)
        self.assertEqual(len(self.mixture.specimens), 1)
        self.assertEqual(len(self.mixture.phases), 1)
        self.assertEqual(len(self.mixture.fractions), 1)
        self.assertEqual(self.mixture.phase_matrix.shape, (1, 1))
        self.assertEqual(self.mixture.phase_matrix[0, 0], None)

    def test_add_multiple(self):
        """Test if addition for multiple phases and specimens works as expected"""
        self.mixture.add_phase_slot("TestPhase", 0.5)
        self.mixture.add_specimen_slot(None, 1.0, 0)
        self.mixture.add_specimen_slot(None, 1.0, 0)
        self.mixture.add_phase_slot("TestPhase2", 0.5)
        self.mixture.add_phase_slot("TestPhase3", 0.5)
        self.assertEqual(len(self.mixture.specimens), 2)
        self.assertEqual(len(self.mixture.phases), 3)
        self.assertEqual(len(self.mixture.fractions), 3)
        self.assertEqual(self.mixture.phase_matrix.shape, (2, 3))

    def test_del_phase_slot(self):
        """Test if deleting a phase works as expected"""
        self.mixture.add_phase_slot("TestPhase1", 0.1)
        self.mixture.add_phase_slot("TestPhase2", 0.1)
        self.mixture.del_phase_slot(1)
        self.assertEqual(len(self.mixture.phases), 1)
        self.assertEqual(len(self.mixture.fractions), 1)
        self.assertEqual(self.mixture.phase_matrix.shape, (0, 1))
        self.mixture.del_phase_slot(0)
        self.assertEqual(len(self.mixture.phases), 0)
        self.assertEqual(len(self.mixture.fractions), 0)
        self.assertEqual(self.mixture.phase_matrix.shape, (0, 0))

    def test_del_specimen_slot(self):
        """Test if deleting a specimen works as expected"""
        self.mixture.add_specimen_slot(None, 0.5, 0)
        self.mixture.add_specimen_slot(None, 0.5, 0)
        self.mixture.del_specimen_slot(1)
        self.assertEqual(len(self.mixture.specimens), 1)
        self.assertEqual(self.mixture.phase_matrix.shape, (1, 0))
        self.mixture.del_specimen_slot(0)
        self.assertEqual(len(self.mixture.specimens), 0)
        self.assertEqual(self.mixture.phase_matrix.shape, (0, 0))

    def test_del_phase_slot_by_name(self):
        self.mixture.add_phase_slot("TestPhase1", 0.1)
        self.mixture.del_phase_slot_by_name("TestPhase1")
        self.assertEqual(len(self.mixture.phases), 0)
        self.assertEqual(len(self.mixture.fractions), 0)
        self.assertEqual(self.mixture.phase_matrix.shape, (0, 0))

    def test_del_specimen_slot_by_object(self):
        dummy = Specimen(name="Test Specimen", parent=self.project)
        self.project.specimens.append(dummy)
        self.mixture.add_specimen_slot(dummy, 0.5, 0)
        self.mixture.del_specimen_slot_by_object(dummy)
        self.assertEqual(len(self.mixture.specimens), 0)
        self.assertEqual(self.mixture.phase_matrix.shape, (0, 0))

    def test_set_specimen(self):
        dummy = Specimen(name="Test Specimen", parent=self.project)
        self.project.specimens.append(dummy)
        self.mixture.add_specimen_slot(None, 0.5, 0)
        self.mixture.set_specimen(0, dummy)
        self.assertEqual(self.mixture.specimens[0], dummy)

    def test_unset_specimen(self):
        dummy = Specimen(name="Test Specimen", parent=self.project)
        self.project.specimens.append(dummy)
        self.mixture.add_specimen_slot(dummy, 0.5, 0)
        self.mixture.unset_specimen(dummy)
        self.assertEqual(self.mixture.specimens[0], None)

    def test_unset_phase(self):
        specimen = Specimen(name="Test Specimen", parent=self.project)
        self.project.specimens.append(specimen)
        self.mixture.add_specimen_slot(specimen, 0.5, 0)
        self.mixture.add_phase_slot("Test Phase1", 0.5)

        dummy = Phase(name="Test Phase", parent=self.project)
        self.project.phases.append(dummy)
        self.mixture.set_phase(0, 0, dummy)
        self.mixture.unset_phase(dummy)
        self.assertEqual(self.mixture.phase_matrix[0, 0], None)

    def test_randomize_empty_mixture(self):
        self.mixture.refiner.randomize()

    def _refinement_setup(self):
        # TODO maybe add some more variation in the type of Phases?
        specimen = Specimen(name="Test Specimen", parent=self.project)
        self.project.specimens.append(specimen)
        phase1 = Phase(name="Test Phase1", parent=self.project)
        self.project.phases.append(phase1)
        phase2 = Phase(name="Test Phase2", parent=self.project)
        self.project.phases.append(phase2)
        self.mixture.add_specimen_slot(specimen, 0.5, 0)
        self.mixture.add_phase_slot("Test Phase1", 0.5)
        self.mixture.add_phase_slot("Test Phase2", 0.5)
        self.mixture.set_phase(0, 0, phase1)
        self.mixture.set_phase(0, 1, phase2)

    def test_randomize(self):
        self._refinement_setup()

        # Mark the attribute(s) for refinement & get their values:
        refinables = []
        for node in self.mixture.refinables.iter_children():
            ref_prop = node.object
            if ref_prop.refinable:
                ref_prop.refine = True
                refinables.append((ref_prop, ref_prop.value))

        # Randomize:
        self.mixture.refiner.randomize()

        # Check all of them have been randomized:
        # It is possible (but unlikely) that the randomized value
        # is the same as the pre-randomized value. If so run this test again
        # to make sure it is really failing.
        for ref_prop, pre_val in refinables:
            self.assertNotEqual(pre_val, ref_prop.value)

    def test_auto_restrict_empy_mixture(self):
        self.mixture.refiner.auto_restrict()

    def test_auto_restrict(self):
        self._refinement_setup()

        # Mark the attribute(s) for refinement & get their values:
        refinables = []
        for node in self.mixture.refinables.iter_children():
            ref_prop = node.object
            if ref_prop.refinable:
                ref_prop.refine = True
                refinables.append((ref_prop, ref_prop.value))

        # Randomize:
        self.mixture.refiner.auto_restrict()

        # Check all of them have been restricted:
        for ref_prop, pre_val in refinables:
            self.assertEqual(pre_val * 0.8, ref_prop.value_min)
            self.assertEqual(pre_val * 1.2, ref_prop.value_max)


    # TODO:
    #  - set_data_object
    #  - optimize
    #  - apply_current_data_object
    #  - update
    #  - get_refinement_method
    #  - setup_refine_options

    pass # end of class
Beispiel #4
0
 def setUp(self):
     mock_settings()
     self.project = Project(name="TestProject")
     self.mixture = Mixture(name="TestMixture", parent=self.project)
Beispiel #5
0
class TestMixture(unittest.TestCase):

    atom_type = None

    def setUp(self):
        mock_settings()
        self.project = Project(name="TestProject")
        self.mixture = Mixture(name="TestMixture", parent=self.project)

    def tearDown(self):
        del self.mixture
        del self.project

    def test_not_none(self):
        self.assertIsNotNone(self.mixture)

    def test_data_object(self):
        self.assertIsNotNone(self.mixture.data_object)

    test_name = create_object_attribute_test("mixture", "name", "Test Name")

    def test_parent(self):
        parent_project = Project(name="Parent2")
        self.mixture.parent = parent_project
        self.assertEqual(self.mixture.parent, parent_project)

    def test_add_phase_slot(self):
        index = self.mixture.add_phase_slot("TestPhase", 0.5)
        self.assertEqual(index, 0, "Adding a phase slot should return the correct index!")

    def test_add_specimen_slot(self):
        index = self.mixture.add_specimen_slot(None, 1.0, 0)
        self.assertEqual(index, 0, "Adding a specimen slot should return the correct index!")

    def test_add_order1(self):
        """Test if addition works when 1st specimen slot is added before 1st phase slot"""
        self.mixture.add_specimen_slot(None, 1.0, 0)
        self.assertEqual(len(self.mixture.specimens), 1)
        self.assertEqual(len(self.mixture.phases), 0)
        self.assertEqual(len(self.mixture.fractions), 0)
        self.assertEqual(self.mixture.phase_matrix.shape, (1, 0))
        self.mixture.add_phase_slot("TestPhase", 0.5)
        self.assertEqual(len(self.mixture.specimens), 1)
        self.assertEqual(len(self.mixture.phases), 1)
        self.assertEqual(len(self.mixture.fractions), 1)
        self.assertEqual(self.mixture.phase_matrix.shape, (1, 1))
        self.assertEqual(self.mixture.phase_matrix[0, 0], None)

    def test_add_order2(self):
        """Test if addition works when 1st phase slot is added before 1st specimen slot"""
        self.mixture.add_phase_slot("TestPhase", 0.5)
        self.assertEqual(len(self.mixture.specimens), 0)
        self.assertEqual(len(self.mixture.phases), 1)
        self.assertEqual(len(self.mixture.fractions), 1)
        self.assertEqual(self.mixture.phase_matrix.shape, (0, 1))
        self.mixture.add_specimen_slot(None, 1.0, 0)
        self.assertEqual(len(self.mixture.specimens), 1)
        self.assertEqual(len(self.mixture.phases), 1)
        self.assertEqual(len(self.mixture.fractions), 1)
        self.assertEqual(self.mixture.phase_matrix.shape, (1, 1))
        self.assertEqual(self.mixture.phase_matrix[0, 0], None)

    def test_add_multiple(self):
        """Test if addition for multiple phases and specimens works as expected"""
        self.mixture.add_phase_slot("TestPhase", 0.5)
        self.mixture.add_specimen_slot(None, 1.0, 0)
        self.mixture.add_specimen_slot(None, 1.0, 0)
        self.mixture.add_phase_slot("TestPhase2", 0.5)
        self.mixture.add_phase_slot("TestPhase3", 0.5)
        self.assertEqual(len(self.mixture.specimens), 2)
        self.assertEqual(len(self.mixture.phases), 3)
        self.assertEqual(len(self.mixture.fractions), 3)
        self.assertEqual(self.mixture.phase_matrix.shape, (2, 3))

    def test_del_phase_slot(self):
        """Test if deleting a phase works as expected"""
        self.mixture.add_phase_slot("TestPhase1", 0.1)
        self.mixture.add_phase_slot("TestPhase2", 0.1)
        self.mixture.del_phase_slot(1)
        self.assertEqual(len(self.mixture.phases), 1)
        self.assertEqual(len(self.mixture.fractions), 1)
        self.assertEqual(self.mixture.phase_matrix.shape, (0, 1))
        self.mixture.del_phase_slot(0)
        self.assertEqual(len(self.mixture.phases), 0)
        self.assertEqual(len(self.mixture.fractions), 0)
        self.assertEqual(self.mixture.phase_matrix.shape, (0, 0))

    def test_del_specimen_slot(self):
        """Test if deleting a specimen works as expected"""
        self.mixture.add_specimen_slot(None, 0.5, 0)
        self.mixture.add_specimen_slot(None, 0.5, 0)
        self.mixture.del_specimen_slot(1)
        self.assertEqual(len(self.mixture.specimens), 1)
        self.assertEqual(self.mixture.phase_matrix.shape, (1, 0))
        self.mixture.del_specimen_slot(0)
        self.assertEqual(len(self.mixture.specimens), 0)
        self.assertEqual(self.mixture.phase_matrix.shape, (0, 0))

    def test_del_phase_slot_by_name(self):
        self.mixture.add_phase_slot("TestPhase1", 0.1)
        self.mixture.del_phase_slot_by_name("TestPhase1")
        self.assertEqual(len(self.mixture.phases), 0)
        self.assertEqual(len(self.mixture.fractions), 0)
        self.assertEqual(self.mixture.phase_matrix.shape, (0, 0))

    def test_del_specimen_slot_by_object(self):
        dummy = Specimen(name="Test Specimen", parent=self.project)
        self.project.specimens.append(dummy)
        self.mixture.add_specimen_slot(dummy, 0.5, 0)
        self.mixture.del_specimen_slot_by_object(dummy)
        self.assertEqual(len(self.mixture.specimens), 0)
        self.assertEqual(self.mixture.phase_matrix.shape, (0, 0))

    def test_set_specimen(self):
        dummy = Specimen(name="Test Specimen", parent=self.project)
        self.project.specimens.append(dummy)
        self.mixture.add_specimen_slot(None, 0.5, 0)
        self.mixture.set_specimen(0, dummy)
        self.assertEqual(self.mixture.specimens[0], dummy)

    def test_unset_specimen(self):
        dummy = Specimen(name="Test Specimen", parent=self.project)
        self.project.specimens.append(dummy)
        self.mixture.add_specimen_slot(dummy, 0.5, 0)
        self.mixture.unset_specimen(dummy)
        self.assertEqual(self.mixture.specimens[0], None)

    def test_unset_phase(self):
        specimen = Specimen(name="Test Specimen", parent=self.project)
        self.project.specimens.append(specimen)
        self.mixture.add_specimen_slot(specimen, 0.5, 0)
        self.mixture.add_phase_slot("Test Phase1", 0.5)

        dummy = Phase(name="Test Phase", parent=self.project)
        self.project.phases.append(dummy)
        self.mixture.set_phase(0, 0, dummy)
        self.mixture.unset_phase(dummy)
        self.assertEqual(self.mixture.phase_matrix[0, 0], None)

    def test_randomize_empty_mixture(self):
        self.mixture.refinement.randomize()

    def _refinement_setup(self):
        # TODO maybe add some more variation in the type of Phases?
        specimen = Specimen(name="Test Specimen", parent=self.project)
        self.project.specimens.append(specimen)
        phase1 = Phase(name="Test Phase1", parent=self.project)
        self.project.phases.append(phase1)
        phase2 = Phase(name="Test Phase2", parent=self.project)
        self.project.phases.append(phase2)
        self.mixture.add_specimen_slot(specimen, 0.5, 0)
        self.mixture.add_phase_slot("Test Phase1", 0.5)
        self.mixture.add_phase_slot("Test Phase2", 0.5)
        self.mixture.set_phase(0, 0, phase1)
        self.mixture.set_phase(0, 1, phase2)

    def test_randomize(self):
        self._refinement_setup()

        # Mark the attribute(s) for refinement & get their values:
        refinables = []
        for node in self.mixture.refinables.iter_children():
            ref_prop = node.object
            if ref_prop.refinable:
                ref_prop.refine = True
                refinables.append((ref_prop, ref_prop.value))

        # Randomize:
        self.mixture.refinement.randomize()

        # Check all of them have been randomized:
        # It is possible (but unlikely) that the randomized value
        # is the same as the pre-randomized value. If so run this test again
        # to make sure it is really failing.
        for ref_prop, pre_val in refinables:
            self.assertNotEqual(pre_val, ref_prop.value)

    def test_auto_restrict_empy_mixture(self):
        self.mixture.refinement.auto_restrict()

    def test_auto_restrict(self):
        self._refinement_setup()

        # Mark the attribute(s) for refinement & get their values:
        refinables = []
        for node in self.mixture.refinables.iter_children():
            ref_prop = node.object
            if ref_prop.refinable:
                ref_prop.refine = True
                refinables.append((ref_prop, ref_prop.value))

        # Randomize:
        self.mixture.refinement.auto_restrict()

        # Check all of them have been restricted:
        for ref_prop, pre_val in refinables:
            self.assertEqual(pre_val * 0.8, ref_prop.value_min)
            self.assertEqual(pre_val * 1.2, ref_prop.value_max)


    # TODO:
    #  - set_data_object
    #  - optimize
    #  - apply_current_data_object
    #  - update
    #  - get_refinement_method
    #  - setup_refine_options

    pass # end of class
Beispiel #6
0
 def create_new_object_proxy(self):
     return Mixture(parent=self.model)
Beispiel #7
0
def create_project_from_sybilla_xml(filename, **kwargs):
    """
        Creates a new project structure from a Sybilla XML file.
        Some information (e.g. the actual XRD pattern) is not present and will
        still need to be imported manually.
    """

    tree = ET.parse(filename)
    root = tree.getroot()
    basename = os.path.basename(filename)

    # Create the project:
    if "name" in kwargs: kwargs.pop("name")
    if "layout_mode" in kwargs: kwargs.pop("layout_mode")
    project = Project(name=basename, layout_mode="FULL", **kwargs)

    # Add a specimen:
    specimen = Specimen(name=basename, parent=project)
    project.specimens.append(specimen)

    # Add a mixture:
    mixture = Mixture(name=basename, auto_run=False, parent=project)
    mixture.add_specimen_slot(specimen, 1.0, 0.0)
    project.mixtures.append(mixture)

    with project.data_changed.ignore():
        with mixture.data_changed.ignore():

            for child in root:
                if child.tag == "basic_params":
                    # Goniometer parameters:
                    step_size = safe_float(child.attrib['step_size'])
                    wavelength = safe_float(child.attrib['lambda']) / 10.0
                    steps = int(1 + (specimen.goniometer.max_2theta - specimen.goniometer.min_2theta) / step_size)

                    specimen.goniometer.min_2theta = safe_float(child.attrib['min2theta'])
                    specimen.goniometer.max_2theta = safe_float(child.attrib['max2theta'])
                    specimen.goniometer.steps = steps
                    specimen.goniometer.wavelength = wavelength
                elif child.tag == "diffractometer":
                    # Some more goniometer parameters, and specimen parameters:
                    specimen.goniometer.radius = safe_float(child.attrib['gonio_radius'])
                    specimen.goniometer.divergence = safe_float(child.attrib['diverg_slit'])
                    specimen.goniometer.soller1 = safe_float(child.attrib['Soller1'])
                    specimen.goniometer.soller2 = safe_float(child.attrib['Soller2'])
                    specimen.sample_length = safe_float(child.attrib['sample_length'])
                elif child.tag == "content":
                    # Content tag contains 'Mixture' data
                    for xmlPhaseContent in child:
                        name = xmlPhaseContent.attrib['name']
                        fraction = safe_float(xmlPhaseContent.attrib['content']) / 100.
                        mixture.add_phase_slot(name, fraction)
                elif child.tag == "mixture":
                    # Mixture tag corresponds with the phases in the project level,
                    # not an actual Mixture object:
                    for xmlPhase in child:
                        name = xmlPhase.attrib['name']
                        sigma = xmlPhase.attrib['sigma_star']
                        csds = safe_float(xmlPhase.find('distribution').attrib['Tmean'])
                        G = 1
                        R = 0
                        W = [1.0, ]
                        if xmlPhase.attrib['type'] != 'mono':
                            prob = xmlPhase.find('probability')
                            G = int(prob.attrib['no_of_comp'])
                            R = int(prob.attrib['R'])

                        # create phase and add to project:
                        phase = Phase(name=name, sigma_star=sigma, G=G, R=R, parent=project)
                        phase.CSDS_distribution.average = csds
                        project.phases.append(phase)

                        # set probability:
                        if R == 0 and G != 1:
                            xmlW = prob.find('W')
                            W = np.array([ float(int(safe_float(xmlW.attrib[string.ascii_lowercase[i]]) * 1000.)) / 1000. for i in range(G) ])
                            for i in range(G - 1):
                                setattr(phase.probabilities, "F%d" % (i + 1), W[i] / np.sum(W[i:]))
                        if R == 1 and G == 2:
                            pass  # TODO
                        # ... TODO other probs

                        # parse components:
                        for i, layer in enumerate(xmlPhase.findall("./layer_and_edge/layer")):

                            component = phase.components[i]
                            component.name = layer.attrib['name']

                            component.d001 = safe_float(layer.attrib['d_spacing']) / 10.0
                            component.default_c = safe_float(layer.attrib['d_spacing']) / 10.0
                            component.delta_c = safe_float(layer.attrib['d_spacing_delta']) / 10.0

                            component.ucp_b.value = 0.9

                            component.ucp_a.factor = 0.57735
                            component.ucp_a.prop = (component, 'cell_b')
                            component.ucp_a.enabled = True


                            atom_type_map = {
                                # "NH4": "FIXME"
                                "K": "K1+",
                                "O": "O1-",
                                "Si": "Si2+",
                                "OH": "OH1-",
                                "Fe": "Fe1.5+",
                                "Al": "Al1.5+",
                                "Mg": "Mg1+",
                                "H2O": "H2O",
                                "Gly": "Glycol",
                                "Ca": "Ca2+",
                                "Na": "Na1+",
                            }

                            # add atoms:
                            fe_atom = None
                            encountered_oxygen = False
                            for atom in layer.findall("atom"):
                                atom_type_name = atom_type_map.get(atom.attrib['type'], None)
                                if atom_type_name:
                                    if atom_type_name == "O1-":
                                        # From this point we're dealing with layer atoms
                                        encountered_oxygen = True
                                    atom = Atom(
                                        name=atom.attrib['type'],
                                        default_z=safe_float(atom.attrib['position']) / 10.0,
                                        pn=safe_float(atom.attrib['content']),
                                        atom_type_name=atom_type_name,
                                        parent=component
                                    )
                                    if encountered_oxygen:
                                        component.layer_atoms.append(atom)
                                    else:
                                        component.interlayer_atoms.append(atom)
                                    atom.resolve_json_references()
                                    # Assume this is the octahedral iron...
                                    if encountered_oxygen and atom_type_name == "Fe1.5+":
                                        fe_atom = atom

                            # Set the atom relation
                            if fe_atom is not None:
                                component.ucp_b.constant = 0.9
                                component.ucp_b.factor = 0.0043
                                component.ucp_b.prop = (fe_atom, 'pn')
                                component.ucp_b.enabled = True

                pass # end of if
            pass # end of for


            # Map phases onto mixture names:
            for phase in project.phases:
                for slot, phase_name in enumerate(mixture.phases):
                    if phase.name == phase_name:
                        mixture.set_phase(0, slot, phase)

    return project
Beispiel #8
0
def create_project_from_sybilla_xml(filename, **kwargs):
    """
        Creates a new project structure from a Sybilla XML file.
        Some information (e.g. the actual XRD pattern) is not present and will
        still need to be imported manually.
    """

    tree = ET.parse(filename)
    root = tree.getroot()
    basename = os.path.basename(filename)

    # Create the project:
    if "name" in kwargs: kwargs.pop("name")
    if "layout_mode" in kwargs: kwargs.pop("layout_mode")
    project = Project(name=basename, layout_mode="FULL", **kwargs)

    # Add a specimen:
    specimen = Specimen(name=basename, parent=project)
    project.specimens.append(specimen)

    # Add a mixture:
    mixture = Mixture(name=basename, auto_run=False, parent=project)
    mixture.add_specimen_slot(specimen, 1.0, 0.0)
    project.mixtures.append(mixture)

    with project.data_changed.ignore():
        with mixture.data_changed.ignore():

            for child in root:
                if child.tag == "basic_params":
                    # Goniometer parameters:
                    step_size = safe_float(child.attrib['step_size'])
                    wavelength = safe_float(child.attrib['lambda']) / 10.0
                    steps = int(1 +
                                (specimen.goniometer.max_2theta -
                                 specimen.goniometer.min_2theta) / step_size)

                    specimen.goniometer.min_2theta = safe_float(
                        child.attrib['min2theta'])
                    specimen.goniometer.max_2theta = safe_float(
                        child.attrib['max2theta'])
                    specimen.goniometer.steps = steps
                    specimen.goniometer.wavelength = wavelength
                elif child.tag == "diffractometer":
                    # Some more goniometer parameters, and specimen parameters:
                    specimen.goniometer.radius = safe_float(
                        child.attrib['gonio_radius'])
                    specimen.goniometer.divergence = safe_float(
                        child.attrib['diverg_slit'])
                    specimen.goniometer.soller1 = safe_float(
                        child.attrib['Soller1'])
                    specimen.goniometer.soller2 = safe_float(
                        child.attrib['Soller2'])
                    specimen.sample_length = safe_float(
                        child.attrib['sample_length'])
                elif child.tag == "content":
                    # Content tag contains 'Mixture' data
                    for xmlPhaseContent in child:
                        name = xmlPhaseContent.attrib['name']
                        fraction = safe_float(
                            xmlPhaseContent.attrib['content']) / 100.
                        mixture.add_phase_slot(name, fraction)
                elif child.tag == "mixture":
                    # Mixture tag corresponds with the phases in the project level,
                    # not an actual Mixture object:
                    for xmlPhase in child:
                        name = xmlPhase.attrib['name']
                        sigma = xmlPhase.attrib['sigma_star']
                        csds = safe_float(
                            xmlPhase.find('distribution').attrib['Tmean'])
                        G = 1
                        R = 0
                        W = [
                            1.0,
                        ]
                        if xmlPhase.attrib['type'] != 'mono':
                            prob = xmlPhase.find('probability')
                            G = int(prob.attrib['no_of_comp'])
                            R = int(prob.attrib['R'])

                        # create phase and add to project:
                        phase = Phase(name=name,
                                      sigma_star=sigma,
                                      G=G,
                                      R=R,
                                      parent=project)
                        phase.CSDS_distribution.average = csds
                        project.phases.append(phase)

                        # set probability:
                        if R == 0 and G != 1:
                            xmlW = prob.find('W')
                            W = np.array([
                                float(
                                    int(
                                        safe_float(xmlW.attrib[
                                            string.ascii_lowercase[i]]) *
                                        1000.)) / 1000. for i in range(G)
                            ])
                            for i in range(G - 1):
                                setattr(phase.probabilities, "F%d" % (i + 1),
                                        W[i] / np.sum(W[i:]))
                        if R == 1 and G == 2:
                            pass  # TODO
                        # ... TODO other probs

                        # parse components:
                        for i, layer in enumerate(
                                xmlPhase.findall("./layer_and_edge/layer")):

                            component = phase.components[i]
                            component.name = layer.attrib['name']

                            component.d001 = safe_float(
                                layer.attrib['d_spacing']) / 10.0
                            component.default_c = safe_float(
                                layer.attrib['d_spacing']) / 10.0
                            component.delta_c = safe_float(
                                layer.attrib['d_spacing_delta']) / 10.0

                            component.ucp_b.value = 0.9

                            component.ucp_a.factor = 0.57735
                            component.ucp_a.prop = (component, 'cell_b')
                            component.ucp_a.enabled = True

                            atom_type_map = {
                                # "NH4": "FIXME"
                                "K": "K1+",
                                "O": "O1-",
                                "Si": "Si2+",
                                "OH": "OH1-",
                                "Fe": "Fe1.5+",
                                "Al": "Al1.5+",
                                "Mg": "Mg1+",
                                "H2O": "H2O",
                                "Gly": "Glycol",
                                "Ca": "Ca2+",
                                "Na": "Na1+",
                            }

                            # add atoms:
                            fe_atom = None
                            encountered_oxygen = False
                            for atom in layer.findall("atom"):
                                atom_type_name = atom_type_map.get(
                                    atom.attrib['type'], None)
                                if atom_type_name:
                                    if atom_type_name == "O1-":
                                        # From this point we're dealing with layer atoms
                                        encountered_oxygen = True
                                    atom = Atom(
                                        name=atom.attrib['type'],
                                        default_z=safe_float(
                                            atom.attrib['position']) / 10.0,
                                        pn=safe_float(atom.attrib['content']),
                                        atom_type_name=atom_type_name,
                                        parent=component)
                                    if encountered_oxygen:
                                        component.layer_atoms.append(atom)
                                    else:
                                        component.interlayer_atoms.append(atom)
                                    atom.resolve_json_references()
                                    # Assume this is the octahedral iron...
                                    if encountered_oxygen and atom_type_name == "Fe1.5+":
                                        fe_atom = atom

                            # Set the atom relation
                            if fe_atom is not None:
                                component.ucp_b.constant = 0.9
                                component.ucp_b.factor = 0.0043
                                component.ucp_b.prop = (fe_atom, 'pn')
                                component.ucp_b.enabled = True

                pass  # end of if
            pass  # end of for

            # Map phases onto mixture names:
            for phase in project.phases:
                for slot, phase_name in enumerate(mixture.phases):
                    if phase.name == phase_name:
                        mixture.set_phase(0, slot, phase)

    return project