private void ProposeMoleculeWithCommonFormula(Peptide peptide) { // Examine any provided formulas (including parent molecule and/or precursor ions) and find common basis ProposedMolecule = peptide.CustomMolecule; var precursorsWithFormulas = _precursorRawDetails.Where(d => !string.IsNullOrEmpty(d._formulaUnlabeled)).ToList(); var parentFormula = peptide.CustomMolecule.UnlabeledFormula; var commonFormula = string.IsNullOrEmpty(parentFormula) ? BioMassCalc.MONOISOTOPIC.FindFormulaIntersectionUnlabeled( precursorsWithFormulas.Select(p => p._formulaUnlabeled)) : parentFormula; // Check for consistent and correctly declared precursor formula+adduct var precursorsWithFormulasAndAdducts = precursorsWithFormulas.Where(d => !Adduct.IsNullOrEmpty(d._nominalAdduct)).ToList(); if (precursorsWithFormulasAndAdducts.Any() && precursorsWithFormulas.All( d => d._formulaUnlabeled.Equals(precursorsWithFormulasAndAdducts[0]._formulaUnlabeled))) { commonFormula = precursorsWithFormulasAndAdducts[0]._formulaUnlabeled; } if (!string.IsNullOrEmpty(commonFormula)) { var parentComposition = Molecule.ParseExpression(commonFormula); // Check for children proposing to label more atoms than parent provides, adjust parent as needed foreach (var precursor in _precursorRawDetails.Where(d => d._labels != null)) { foreach (var kvpIsotopeCount in precursor._labels) { var unlabeled = BioMassCalc.UnlabeledFromIsotopeSymbol(kvpIsotopeCount.Key); int parentCount; parentComposition.TryGetValue(unlabeled, out parentCount); if (kvpIsotopeCount.Value > parentCount) { // Child proposes to label more of an atom than the parent possesses (seen in the wild) - update the parent commonFormula = Molecule.AdjustElementCount(commonFormula, unlabeled, kvpIsotopeCount.Value - parentCount); parentComposition = Molecule.ParseExpression(commonFormula); } } } if (!Equals(peptide.CustomMolecule.Formula, commonFormula)) { ProposedMolecule = new CustomMolecule(commonFormula, peptide.CustomMolecule.Name); } } }