Converts a chemical formula to an atomic fraction :class:`dict`.

    Args:
        formula (str): chemical formula, like Al2O3. No wildcard are accepted.
551707
def convert_formula_to_atomic_fractions(formula):
    
    mole_fractions = {}
    total_mole_fraction = 0.0

    for match in CHEMICAL_FORMULA_PATTERN.finditer(formula):
        symbol, mole_fraction = match.groups()

        z = pyxray.element_atomic_number(symbol.strip())

        if mole_fraction == '':
            mole_fraction = 1.0
        mole_fraction = float(mole_fraction)

        mole_fraction = float(mole_fraction)
        mole_fractions[z] = mole_fraction
        total_mole_fraction += mole_fraction

    # Calculate atomic fractions
    atomic_fractions = {}
    for z, mole_fraction in mole_fractions.items():
        atomic_fractions[z] = mole_fraction / total_mole_fraction

    return atomic_fractions
682167
def __parse_chemical_data():
    ''''''
    filename = get_file('chemical_data.tsv')

    with io.open(filename, 'r', encoding='cp1252') as textfile:
        next(textfile)

        for line in textfile:
            tokens = line.strip().split('\t')

            if tokens[3] == 'FORMULA':
                # Many seemingly contradictory formulae exist,
                # depending upon the source database
                chebi_id = int(tokens[1])

                if chebi_id not in __FORMULAE:
                    __FORMULAE[chebi_id] = []

                # Append formula:
                form = Formula(tokens[4], tokens[2])
                __FORMULAE[chebi_id].append(form)

            elif tokens[3] == 'MASS':
                __MASSES[int(tokens[1])] = float(tokens[4])

            elif tokens[3] == 'CHARGE':
                __CHARGES[int(tokens[1])] = int(tokens[4]
                                                if tokens[4][-1] != '-'
                                                else '-' + tokens[4][:-1])
1203178
def calculate_ideal_atomic_percent(pif):
    
    if not isinstance(pif, ChemicalSystem):
        return pif
    if not pif.chemical_formula:
        return pif
    else:
        expanded_formula_no_special_char = _expand_formula_(
            pif.chemical_formula)
        element_array = _create_emprical_compositional_array_(
            expanded_formula_no_special_char)
        appended_e_array = _add_atomic_percents_(element_array)
        for e in appended_e_array:
            # Checks if a Composition element decribing that element already
            # exists.
            if _get_element_in_pif_composition_(pif, e["symbol"]):
                # If it exists, it removes the old Composition object, and
                # inserts a new one with ideal atomic percent added.
                in_pif = _get_element_in_pif_composition_(pif, e["symbol"])
                comp = in_pif[0]
                pif.composition.pop(in_pif[1])
                comp.idealAtomicPercent = e["atomic_percent"]
                pif.composition.append(comp)
            else:
                # If not, it creates a new Composition object with the element
                # and ideal atomic percent.
                comp = Composition()
                comp.element = e["symbol"]
                comp.idealAtomicPercent = e["atomic_percent"]
                pif.composition.append(comp)
        return pif
996484
def ingredient_from_validated_dict(ingr_dict, selectable):
    

    validator = IngredientValidator(schema=ingr_dict['kind'])
    if not validator.validate(ingr_dict):
        raise Exception(validator.errors)
    ingr_dict = validator.document

    kind = ingr_dict.pop('kind', 'Metric')
    IngredientClass = ingredient_class_for_name(kind)

    if IngredientClass is None:
        raise BadIngredient('Unknown ingredient kind')

    args = []
    for fld in ingr_dict.pop('_fields', []):
        args.append(parse_validated_field(ingr_dict.pop(fld), selectable))

    return IngredientClass(*args, **ingr_dict)
1367669
def ingredient_from_dict(ingr_dict, selectable):
    

    # TODO: This is deprecated in favor of
    # ingredient_from_validated_dict

    # Describe the required params for each kind of ingredient
    # The key is the parameter name, the value is one of
    # field: A parse_field with aggregation=False
    # aggregated_field: A parse_field with aggregation=True
    # condition: A parse_condition

    params_lookup = {
        'Dimension': {
            'field': 'field'
        },
        'LookupDimension': {
            'field': 'field'
        },
        'IdValueDimension':
            OrderedDict(id_field='field', field='field'),
        'Metric': {
            'field': 'aggregated_field'
        },
        'DivideMetric':
            OrderedDict(
                numerator_field='aggregated_field',
                denominator_field='aggregated_field'
            ),
        'WtdAvgMetric':
            OrderedDict(field='field', weight='field')
    }

    format_lookup = {
        'comma': ',.0f',
        'dollar': '$,.0f',
        'percent': '.0%',
        'comma1': ',.1f',
        'dollar1': '$,.1f',
        'percent1': '.1%',
        'comma2': ',.2f',
        'dollar2': '$,.2f',
        'percent2': '.2%',
    }

    kind = ingr_dict.pop('kind', 'Metric')
    IngredientClass = ingredient_class_for_name(kind)

    if IngredientClass is None:
        raise BadIngredient('Unknown ingredient kind')

    params = params_lookup.get(kind, {'field': 'field'})

    args = []
    for k, v in iteritems(params):
        # All the params must be in the dict
        if k not in ingr_dict:
            raise BadIngredient(
                '{} must be defined to make a {}'.format(k, kind)
            )
        if v == 'field':
            statement = parse_field(
                ingr_dict.pop(k, None), selectable, aggregated=False
            )
        elif v == 'aggregated_field':
            statement = parse_field(
                ingr_dict.pop(k, None), selectable, aggregated=True
            )
        elif v == 'condition':
            statement = parse_condition(
                ingr_dict.pop(k, None), selectable, aggregated=True
            )
        else:
            raise BadIngredient('Do not know what this is')

        args.append(statement)
    # Remaining properties in ingr_dict are treated as keyword args

    # If the format string exists in format_lookup, use the value otherwise
    # use the original format
    if 'format' in ingr_dict:
        ingr_dict['format'] = format_lookup.get(
            ingr_dict['format'], ingr_dict['format']
        )
    return IngredientClass(*args, **ingr_dict)
1073138
def get_atom_type_symbol(cls,calc,**kwargs):
        
        parameters = calc.out.output
        dictionary = parameters.get_dict()
        if 'basis_set' not in dictionary.keys():
            return None
        return sorted(dictionary['basis_set'].keys())
956897
def chemical_formula(self):
        """"""
        counts = {}
        for number in self.numbers:
            counts[number] = counts.get(number, 0)+1
        items = []
        for number, count in sorted(counts.items(), reverse=True):
            if count == 1:
                items.append(periodic[number].symbol)
            else:
                items.append("%s%i" % (periodic[number].symbol, count))
        return "".join(items)
1056713
def _convert_eq(self, eq):
        
        rename = dict(enumerate(self.index))
        eq['eq_sets'] = {rename[k]: {rename[x] for x in v}
                         for k, v in eq['eq_sets'].items()}
        eq['sym_ops'] = {rename[k]: {rename[x]: v[x] for x in v}
                         for k, v in eq['sym_ops'].items()}
        try:
            sym_mol = self.from_pymatgen_molecule(eq['sym_mol'])
            sym_mol.index = self.index
            eq['sym_mol'] = sym_mol._to_numeric()
        except KeyError:
            pass
153907
def atoms(lines):
    
    # Convert sdf style charge to actual charge
    conv_charge_table = {0: 0, 1: 3, 2: 2, 3: 1, 4: 0, 5: -1, 6: -2, 7: -3}
    results = {}
    for i, line in enumerate(lines):
        symbol = line[31:34].rstrip()
        try:
            atom = Atom(symbol)
        except KeyError:
            raise ValueError(symbol)
        xpos = float(line[0:10])
        ypos = float(line[10:20])
        zpos = float(line[20:30])
        atom.coords = (xpos, ypos, zpos)
        atom.mass_diff = int(line[34:37])
        old_sdf_charge = int(line[37:40])
        atom.charge = conv_charge_table[old_sdf_charge]
        if old_sdf_charge == 4:
            atom.radical = 1
        # atom.stereo_flag = int(line[40:43])  # Not used
        # valence = int(line[46:49])
        # if valence:
        #     atom.valence = valence
        results[i + 1] = {"atom": atom}
    return results
293210
def select_molecules(name):
    ''''''
    mol_formula = current_system().get_derived_molecule_array('formula')
    mask = mol_formula == name
    ind = current_system().mol_to_atom_indices(mask.nonzero()[0])

    selection = {'atoms': Selection(ind, current_system().n_atoms)}

    # Need to find the bonds between the atoms
    b = current_system().bonds
    if len(b) == 0:
        selection['bonds'] = Selection([], 0)
    else:
        molbonds = np.zeros(len(b), 'bool')
        for i in ind:
            matching = (i == b).sum(axis=1).astype('bool')
            molbonds[matching] = True
        
        selection['bonds'] = Selection(molbonds.nonzero()[0], len(b))

    return select_selection(selection)
15002
private static BigDecimal doCalculate(String formula) throws Exception {
        Stack<BigDecimal> stack = new Stack<>();
        BigDecimal result = BigDecimal.valueOf(0);
        BigDecimal number = BigDecimal.valueOf(0);
        char sign = '+';
        boolean isDecimal = false;
        BigDecimal decimalSign = new BigDecimal(0.1);

        for (int i = 0; i < formula.length(); i++) {
            char c = formula.charAt(i);
            if (Character.isDigit(c)) {
                BigDecimal num = new BigDecimal(c - '0');
                number = isDecimal ? number.add(num.multiply(decimalSign)) : num.add(number.multiply(BigDecimal
                        .valueOf(10)));
                decimalSign = decimalSign.multiply(BigDecimal.valueOf(0.1));
            } else if (c == '.') {
                isDecimal = true;
                decimalSign = BigDecimal.valueOf(0.1);
            } else if (c == '(') {
                BigDecimal[] res = calculateInlineFormula(i + 1, formula);
                number = number.compareTo(BigDecimal.valueOf(0)) == 0 ? res[0] : number.multiply(res[0]);
                i = res[1].intValue();
            }
            boolean isNotDigit = (!Character.isDigit(c) && c != '.' && c != '(') || i == formula.length() - 1;
            if (isNotDigit) {
                if (sign == '+') {
                    stack.push(number);
                } else if (sign == '-') {
                    stack.push(number.multiply(BigDecimal.valueOf(-1)));
                } else if (sign == '*') {
                    stack.push(number.multiply(stack.pop()));
                } else if (sign == '/') {
                    stack.push(stack.pop().divide(number, getPrecision(), BigDecimal.ROUND_HALF_UP));
                }
                sign = c;
                isDecimal = false;
                number = BigDecimal.valueOf(0);
            }
        }
        for (BigDecimal i : stack) {
            result = result.add(i);
        }
        return result.setScale(getPrecision(), BigDecimal.ROUND_HALF_UP);
    }
1193450
def get_composition(self):
        '''
        '''
        strc = self.get_output_structure()
        counts = Counter(strc.get_chemical_symbols())
        return ''.join(k if counts[k]==1 else '%s%d'%(k,counts[k]) \
                for k in sorted(counts))
359797
public static Backbone compute(final Formula formula) {
        return compute(formula, formula.variables(), BackboneType.POSITIVE_AND_NEGATIVE);
    }
82492
def __calculate_atoms_per_cm3(self, used_lock=False):
        """"""
        stack = self.stack
        _density_lock = self.density_lock

        for _name_of_compound in stack.keys():
            if used_lock and _density_lock[_name_of_compound]:
                continue
            molar_mass_layer, atoms_per_cm3_layer = _utilities.get_atoms_per_cm3_of_layer(
                compound_dict=stack[_name_of_compound])
            # Update layer molar mass
            stack[_name_of_compound]['molar_mass'] = {'value': molar_mass_layer,
                                                      'units': 'g/mol'}
            # Update atoms per cm3
            stack[_name_of_compound]['atoms_per_cm3'] = atoms_per_cm3_layer
            for _index, _name_of_ele in enumerate(stack[_name_of_compound]['elements']):
                stack[_name_of_compound][_name_of_ele]['atoms_per_cm3'] = atoms_per_cm3_layer * \
                                                                          stack[_name_of_compound][
                                                                              'stoichiometric_ratio'][_index]
        self.stack = stack
357476
def get_alpha(self, *args):
        
        for x in args:
            self.EF += get_ef(self._unit, x)
        molecular = self.PTN + self.EF - self.SCN + 1
        denominator = self.NN + self.SPN + self.SCN - self.EF + 1
        if molecular <= 0:
            molecular = 1
        if denominator <=0:
            denominator = 1
        fraction = molecular / denominator
        if args:
            alpha = ln(fraction)
            log('debug',
                '当前参数如下：\n文本行：【{}】\n纯文本数：【{}】，强化因子：【{}】，数字数：【{}】，特殊字符数：【{}】，特殊中文字符：【{}】，字符数：【{}】\n风险因子：【{}】，句数：【{}】'.format(
                    self._unit, self.PTN, self.EF, self.NN, self.SPN, self.SCN, self.NC, alpha, self.SN))
        else:
            alpha = ln(fraction) + self.SN
            log('debug',
                '当前参数如下：\n文本行：【{}】\n纯文本数：【{}】，句数：【{}】，数字数：【{}】，特殊字符数：【{}】，特殊中文字符：【{}】，字符数：【{}】\n风险因子：【{}】'.format(
                    self._unit, self.PTN, self.SN, self.NN, self.SPN, self.SCN, self.NC, alpha))
        return alpha
824784
def stoichiometry( self ):
        
        return Counter( { label: number for label, number in zip( self.atoms, self.atom_numbers ) } )
634901
def from_string(cls, contents):
        
        mol = None
        charge = None
        spin_multiplicity = None
        params = dict()
        lines = contents.split('\n')
        parse_section = False
        section_name = None
        section_text = []
        ghost_atoms = None
        for line_num, line in enumerate(lines):
            l = line.strip().lower()

            if len(l) == 0:
                continue
            if (not parse_section) and (l == "$end" or not l.startswith("$")):
                raise ValueError("Format error, parsing failed")
            if parse_section and l != "$end":
                section_text.append(line)
            if l.startswith("$") and not parse_section:
                parse_section = True
                section_name = l[1:]
                available_sections = ["comment", "molecule", "rem"] + \
                    sorted(list(cls.optional_keywords_list))
                if section_name not in available_sections:
                    raise ValueError("Unrecognized keyword " + line.strip() +
                                     " at line " + str(line_num))
                if section_name in params:
                    raise ValueError("duplicated keyword " + line.strip() +
                                     "at line " + str(line_num))
            if parse_section and l == "$end":
                func_name = "_parse_" + section_name
                if func_name not in QcTask.__dict__:
                    raise Exception(func_name + " is not implemented yet, "
                                    "please implement it")
                parse_func = QcTask.__dict__[func_name].__get__(None, QcTask)
                if section_name == "molecule":
                    mol, charge, spin_multiplicity, ghost_atoms = parse_func(section_text)
                else:
                    d = parse_func(section_text)
                    params[section_name] = d
                parse_section = False
                section_name = None
                section_text = []
        if parse_section:
            raise ValueError("Format error. " + section_name + " is not "
                             "terminated")
        jobtype = params["rem"]["jobtype"]
        title = params.get("comment", None)
        exchange = params["rem"].get("exchange", "hf")
        method = params["rem"].get("method", None)
        correlation = params["rem"].get("correlation", None)
        basis_set = params["rem"]["basis"]
        aux_basis_set = params["rem"].get("aux_basis", None)
        ecp = params["rem"].get("ecp", None)
        optional_params = None
        op_keys = set(params.keys()) - {"comment", "rem"}
        if len(op_keys) > 0:
            optional_params = dict()
            for k in op_keys:
                optional_params[k] = params[k]
        return QcTask(molecule=mol, charge=charge,
                      spin_multiplicity=spin_multiplicity,
                      jobtype=jobtype, title=title,
                      exchange=exchange, correlation=correlation,
                      basis_set=basis_set, aux_basis_set=aux_basis_set,
                      ecp=ecp, rem_params=params["rem"],
                      optional_params=optional_params,
                      ghost_atoms=ghost_atoms,
                      method=method)