def convert_rows(self, material): row = OrderedDict() key = self._create_label('Name') value = self._format_value(material.name) row[key] = value key = self._create_label('Color') color = matplotlib.colors.to_hex(material.color) value = tags.span(color, style='color: ' + color) row[key] = value key = self._create_label('Density', 'kg/m^3') value = self._format_value(material.density_kg_per_m3, 'kg/m^3', Material.DENSITY_TOLERANCE_kg_per_m3) row[key] = value for z, wf in sorted(material.composition.items()): key = self._create_label(pyxray.element_symbol(z)) value = self._format_value( wf, tolerance=Material.WEIGHT_FRACTION_TOLERANCE) row[key] = value rows = super().convert_rows(material) rows.append(row) return rows
def test_from_pure(z): comp = Composition.from_pure(z) assert comp.mass_fractions[z] == pytest.approx(1.0, 1e-4) assert comp.atomic_fractions[z] == pytest.approx(1.0, 1e-4) assert comp.formula == pyxray.element_symbol(z) assert comp.is_normalized()
def convert_document(self, builder): super().convert_document(builder) # Standards section = builder.add_section() section.add_title("Standard(s)") if self.standard_materials: table = section.require_table(self.TABLE_STANDARD) table.add_column("Element") table.add_column("Material") for z, material in self.standard_materials.items(): row = { "Element": pyxray.element_symbol(z), "Material": material.name } table.add_row(row) section = builder.add_section() section.add_title("Materials") for material in self.standard_materials.values(): section.add_entity(material) else: section.add_text("No standard defined")
def from_pure(cls, z): """ Creates a pure composition. Args: z (int): atomic number """ return cls(cls._key, {z: 1.0}, {z: 1.0}, pyxray.element_symbol(z))
def selectionSymbol(self): selection = self.selection() if self.isMultipleSelection(): return frozenset(map(pyxray.element_symbol, selection)) else: if selection is None: return None else: return pyxray.element_symbol(selection)
def _setup_region_material(region, material): region.removeAllElements() for z, fraction in material.composition.items(): region.addElement(pyxray.element_symbol(z), weight_fraction=fraction) region.update() # Calculate number of elements, mean atomic number region.User_Density = True region.Rho = material.density_g_per_cm3 region.Name = material.name
def convert_document(self, builder): super().convert_document(builder) table = builder.require_table(self.TABLE_MATERIAL) table.add_column("Name") table.add_column("Color") table.add_column("Density", "kg/m^3", self.DENSITY_TOLERANCE_kg_per_m3) for z in sorted(self.composition): name = pyxray.element_symbol(z) table.add_column(name, tolerance=self.WEIGHT_FRACTION_TOLERANCE) row = { "Name": self.name, "Color": matplotlib.colors.to_hex(self.color), "Density": self.density_kg_per_m3, } for z, wf in self.composition.items(): symbol = pyxray.element_symbol(z) row[symbol] = wf table.add_row(row)
def _validate_analysis_kratio(self, analysis, options, erracc): standard_materials = apply_lazy(analysis.standard_materials, analysis, options) for z, material in standard_materials.items(): self._validate_material(material, options, erracc) if z not in material.composition: exc = ValueError( "Standard for element {0} does not have this element in its composition" .format(pyxray.element_symbol(z))) erracc.add_exception(exc)
def generate_name(atomic_fractions): """ Generates a name from the composition. The name is generated on the basis of a classical chemical formula. """ if not atomic_fractions: return '' if len(atomic_fractions) == 1: z = list(atomic_fractions.keys())[0] return pyxray.element_symbol(z) symbols = [] fractions = [] for z in sorted(atomic_fractions.keys(), reverse=True): symbols.append(pyxray.element_symbol(z)) fractions.append(Fraction(atomic_fractions[z]).limit_denominator()) # Find gcd of the fractions gcds = [] for a, b in itertools.combinations(fractions, 2): gcds.append(math.gcd(a.denominator, b.denominator)) smallest_gcd = min(gcds) # Write formula name = '' for symbol, fraction in zip(symbols, fractions): mole_fraction = int(fraction * smallest_gcd) if mole_fraction == 0: continue elif mole_fraction == 1: name += "%s" % symbol else: name += '%s%i' % (symbol, mole_fraction) return name
def generate_name(atomic_fractions): """ Generates a name from the composition. The name is generated on the basis of a classical chemical formula. """ if not atomic_fractions: return "" if len(atomic_fractions) == 1: z = list(atomic_fractions.keys())[0] return pyxray.element_symbol(z) symbols = [] fractions = [] for z in sorted(atomic_fractions.keys(), reverse=True): symbols.append(pyxray.element_symbol(z)) fractions.append(Fraction(atomic_fractions[z]).limit_denominator()) # Find gcd of the fractions gcds = [] for a, b in itertools.combinations(fractions, 2): gcds.append(math.gcd(a.denominator, b.denominator)) smallest_gcd = min(gcds) # Write formula name = "" for symbol, fraction in zip(symbols, fractions): mole_fraction = int(fraction * smallest_gcd) if mole_fraction == 0: continue elif mole_fraction == 1: name += "%s" % symbol else: name += "%s%i" % (symbol, mole_fraction) return name
def convert(self, material): s = super().convert(material) for z, wf in material.composition.items(): symbol = pyxray.element_symbol(z) name = '{} weight fraction'.format(symbol) abbrev = 'wt{}'.format(symbol) tolerance = Material.WEIGHT_FRACTION_TOLERANCE column = NamedSeriesColumn(name, abbrev, tolerance=tolerance) s[column] = wf column = NamedSeriesColumn('density', 'rho', 'kg/m^3', Material.DENSITY_TOLERANCE_kg_per_m3) s[column] = material.density_kg_per_m3 return s
def addElement(self, z=None, fraction=0.0): zs = set(self._composition.keys()) if z is None: available_zs = set(range(1, MAX_Z + 1)) - zs if not available_zs: raise ValueError("No more element can be added") z = sorted(available_zs)[0] elif z in zs: raise ValueError('Element "{0}" already added'.format( pyxray.element_symbol(z))) self._composition[z] = fraction self._update_composition_atomic() self.modelReset.emit()
def _export_material(self, material, options, erracc, region): region.removeAllElements() composition = apply_lazy(material.composition, material, options) for z, fraction in composition.items(): region.addElement(pyxray.element_symbol(z), weight_fraction=fraction) region.update() # Calculate number of elements, mean atomic number region.User_Density = True density_g_per_cm3 = apply_lazy(material.density_g_per_cm3, material, options) region.Rho = density_g_per_cm3 name = apply_lazy(material.name, material, options).strip() region.Name = name
def generate_name(composition): """ Generates a name from the composition. The name is generated on the basis of a classical chemical formula. :arg composition: composition in weight fraction. The composition is specified by a dictionary. The key are atomic numbers and the values weight fractions. No wildcard are accepted. :type composition: :class:`dict` """ composition_atomic = to_atomic(composition) symbols = [] fractions = [] for z in sorted(composition_atomic.keys(), reverse=True): symbols.append(pyxray.element_symbol(z)) fractions.append(int(composition_atomic[z] * 100.0)) # Find gcd of the fractions smallest_gcd = 100 if len(fractions) >= 2: gcds = [] for a, b in itertools.combinations(fractions, 2): gcds.append(math.gcd(a, b)) smallest_gcd = min(gcds) if smallest_gcd == 0.0: smallest_gcd = 100.0 # Write formula name = '' for symbol, fraction in zip(symbols, fractions): fraction /= smallest_gcd if fraction == 0: continue elif fraction == 1: name += "%s" % symbol else: name += '%s%i' % (symbol, fraction) if not name: name = 'Untitled' return name
def _create_name(self, *args): symbol = pyxray.element_symbol(self.element) if self.is_xray_transitionset(): method = pyxray.xray_transitionset_notation else: method = pyxray.xray_transition_notation settings = pymontecarlo.settings preferred_notation = settings.preferred_xrayline_notation preferred_encoding = settings.preferred_xrayline_encoding try: notation = method(self.line, preferred_notation, preferred_encoding) except pyxray.NotFound: notation = method(self.line, 'iupac', preferred_encoding) return '{0} {1}'.format(symbol, notation)
def convert_series(self, builder): super().convert_series(builder) for z, wf in self.composition.items(): symbol = pyxray.element_symbol(z) name = "{} weight fraction".format(symbol) abbrev = "wt{}".format(symbol) tolerance = self.WEIGHT_FRACTION_TOLERANCE builder.add_column(name, abbrev, wf, tolerance=tolerance) builder.add_column( "density", "rho", self.density_kg_per_m3, "kg/m^3", self.DENSITY_TOLERANCE_kg_per_m3, ) return builder
def __init__(self, atomic_number, parent=None): super().__init__(parent) self.setFixedSize(40, 40) self._atomic_number = atomic_number self._symbol = pyxray.element_symbol(atomic_number) self.setText(self._symbol) font = self.font() font.setWeight(QtGui.QFont.Bold) self.setFont(font) self.setSizePolicy( QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding, ) self.setDefault(False) self.setAutoDefault(False)
def convert(self, analysis, level=1): root = super().convert(analysis, level) root += self._create_header(level, 'Standards') rows = [] for z, material in analysis.standard_materials.items(): row = OrderedDict() key = self._create_label('Element') value = self._format_value(pyxray.element_symbol(z)) row[key] = value key = self._create_label('Material') value = self._format_value(material.name) row[key] = value rows.append(row) root += self._create_table(rows) return root
def inner_repr(self): return ", ".join( "{}: {:.4f}".format(pyxray.element_symbol(z), mass_fraction) for z, mass_fraction in self.mass_fractions.items())
def test_from_formula_symbol(z): formula = pyxray.element_symbol(z) comp = Composition.from_formula(formula) assert comp.formula == formula
def inner_repr(self): return ', '.join('{}: {:.4f}'.format(pyxray.element_symbol(z), mass_fraction) for z, mass_fraction in self.mass_fractions.items())
def data(self, index, role=QtCore.Qt.DisplayRole): if not index.isValid(): return None row = index.row() column = index.column() tolerance = Material.WEIGHT_FRACTION_TOLERANCE fmt = "{{:.{:d}f}}".format(max(0, tolerance_to_decimals(tolerance) - 2)) if row < len(self._composition): z = list(self._composition.keys())[row] wf = self._composition[z] af = self._composition_atomic[z] if role == QtCore.Qt.DisplayRole: if column == 0: return pyxray.element_symbol(z) elif column == 1: if wf == "?": return wf else: return fmt.format(wf * 100.0) elif column == 2: return fmt.format(af * 100.0) elif role == QtCore.Qt.UserRole: if column == 0: return z elif column == 1: return wf elif column == 2: return af elif role == QtCore.Qt.TextAlignmentRole: return QtCore.Qt.AlignCenter else: total_wf = sum(self.composition().values()) total_af = 1.0 # Always 100% if role == QtCore.Qt.DisplayRole: if column == 0: return "Total" elif column == 1: return fmt.format(total_wf * 100.0) elif column == 2: return fmt.format(total_af * 100.0) elif role == QtCore.Qt.UserRole: if column == 1: return total_wf elif column == 2: return total_af elif role == QtCore.Qt.TextAlignmentRole: if column == 0: return QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter else: return QtCore.Qt.AlignCenter elif role == QtCore.Qt.FontRole: font = QtGui.QFont() font.setBold(True) return font elif role == QtCore.Qt.BackgroundRole: if not self.isValid(): brush = QtGui.QBrush() brush.setColor(QtGui.QColor(INVALID_COLOR)) brush.setStyle(QtCore.Qt.SolidPattern) return brush
def _get_item_text(self, atomic_number): return pyxray.element_symbol(atomic_number)
def to_repr(composition): """ Returns a repr string from a composition :class:`dict`. """ return ' '.join('{1:g}%{0}'.format(pyxray.element_symbol(z), wf * 100.0) for z, wf in composition.items())