@@ -771,37 +771,14 @@ private static int extractCharge(String formula) {
771771 }
772772
773773 /**
774- * Get the summed exact mass of all isotopes from an MolecularFormula. It
775- * assumes isotope masses to be preset, and returns 0.0 if not.
776- *
777- * @param formula The IMolecularFormula to calculate
778- * @return The summed exact mass of all atoms in this MolecularFormula
774+ * @deprecated calls {@link #getMass(IMolecularFormula, int)} with option
775+ * {@link #MonoIsotopic} and adjusts for charge with
776+ * {@link #correctMass(double, Integer)}. These functions should be used
777+ * directly.
779778 */
779+ @ Deprecated
780780 public static double getTotalExactMass (IMolecularFormula formula ) {
781- double mass = 0.0 ;
782- for (IIsotope isotope : formula .isotopes ()) {
783- try {
784- Integer massNum = isotope .getMassNumber ();
785- Double exactMass = isotope .getExactMass ();
786- if (massNum == null || massNum == 0 ) {
787- IIsotope majorIsotope = Isotopes .getInstance ().getMajorIsotope (isotope .getSymbol ());
788- if (majorIsotope != null )
789- exactMass = majorIsotope .getExactMass ();
790- } else {
791- if (exactMass == null ) {
792- IIsotope temp = Isotopes .getInstance ().getIsotope (isotope .getSymbol (), massNum );
793- if (temp != null )
794- exactMass = temp .getExactMass ();
795- }
796- }
797- if (exactMass != null )
798- mass += exactMass * formula .getIsotopeCount (isotope );
799- } catch (IOException e ) {
800- throw new RuntimeException ("Could not instantiate the IsotopeFactory." );
801- }
802- }
803- if (formula .getCharge () != null ) mass = correctMass (mass , formula .getCharge ());
804- return mass ;
781+ return correctMass (getMass (formula , MonoIsotopic ), formula .getCharge ());
805782 }
806783
807784 /**
@@ -844,48 +821,135 @@ public static double getTotalMassNumber(IMolecularFormula formula) {
844821 return mass ;
845822 }
846823
824+ private static final int MolWeight = 0x1 ;
825+ private static final int AverageWeight = 0x2 ;
826+ private static final int MonoIsotopic = 0x3 ;
827+ private static final int MostAbundant = 0x4 ;
828+
829+ private static double getExactMass (IsotopeFactory isofact , IIsotope atom ) {
830+ if (atom .getExactMass () != null )
831+ return atom .getExactMass ();
832+ else if (atom .getMassNumber () != null )
833+ return isofact .getExactMass (atom .getAtomicNumber (),
834+ atom .getMassNumber ());
835+ else
836+ return isofact .getMajorIsotopeMass (atom .getAtomicNumber ());
837+ }
838+
839+ private static double getMassOrAvg (IsotopeFactory isofact , IIsotope atom ) {
840+ if (atom .getMassNumber () == null ||
841+ atom .getMassNumber () == 0 )
842+ return isofact .getNaturalMass (atom );
843+ else
844+ return getExactMass (isofact , atom );
845+ }
846+
847847 /**
848- * Get the summed natural mass of all elements from an MolecularFormula.
849- *
850- * @param formula The IMolecularFormula to calculate
851- * @return The summed exact mass of all atoms in this MolecularFormula
848+ * Calculate the mass of a molecule, this function takes an optional
849+ * 'mass flavour' that switches the computation type, the flavours are:
850+ * <br>
851+ * <ul>
852+ * <li>{@link #MolWeight} (default) - use and isotopes the natural mass
853+ * unless a specific isotope is specified</li>
854+ * <li>{@link #AverageWeight} - use and isotopes the natural mass even
855+ * if a specific isotope is specified</li>
856+ * <li>{@link #MonoIsotopic} - use and isotopes the major isotope mass
857+ * even if a specific isotope is specified</li>
858+ * <li>{@link #MostAbundant} - use the distribution of isotopes
859+ * based on their abundance and select the most abundant. For example
860+ * C<sub>6</sub>Br<sub>6</sub> would have three <sup>79</sup>Br and
861+ * <sup>81</sup>Br because their abundance is 51 and 49%.
862+ * </ul>
863+ *
864+ * @param mf molecular formula
865+ * @param flav the mass flavour
866+ * @return the mass of the molecule
867+ * @see #MolWeight
868+ * @see #AverageWeight
869+ * @see #MonoIsotopic
870+ * @see #MostAbundant
852871 */
853- public static double getNaturalExactMass (IMolecularFormula formula ) {
854- double mass = 0.0 ;
855- IsotopeFactory factory ;
872+ public static double getMass (IMolecularFormula mf , int flav ) {
873+ final Isotopes isofact ;
856874 try {
857- factory = Isotopes .getInstance ();
875+ isofact = Isotopes .getInstance ();
858876 } catch (IOException e ) {
859- throw new RuntimeException ("Could not instantiate the IsotopeFactory. " );
877+ throw new IllegalStateException ("Could not load Isotopes! " );
860878 }
861- for (IIsotope isotope : formula .isotopes ()) {
862- IElement isotopesElement = formula .getBuilder ().newInstance (IElement .class , isotope );
863- mass += factory .getNaturalMass (isotopesElement ) * formula .getIsotopeCount (isotope );
879+
880+ double mass = 0 ;
881+ switch (flav & 0xf ) {
882+ case MolWeight :
883+ for (IIsotope iso : mf .isotopes ()) {
884+ mass += mf .getIsotopeCount (iso ) *
885+ getMassOrAvg (isofact , iso );
886+ }
887+ break ;
888+ case AverageWeight :
889+ for (IIsotope iso : mf .isotopes ()) {
890+ mass += mf .getIsotopeCount (iso ) *
891+ isofact .getNaturalMass (iso .getAtomicNumber ());
892+ }
893+ break ;
894+ case MonoIsotopic :
895+ for (IIsotope iso : mf .isotopes ()) {
896+ mass += mf .getIsotopeCount (iso ) *
897+ getExactMass (isofact , iso );
898+ }
899+ break ;
900+ case MostAbundant :
901+ IMolecularFormula mamf = getMostAbundant (mf );
902+ if (mamf != null )
903+ mass = getMass (mamf , MonoIsotopic );
904+ break ;
864905 }
865906 return mass ;
866907 }
867908
868909 /**
869- * Get the summed major isotopic mass of all elements from an MolecularFormula.
910+ * Calculate the mass of a molecule, this function takes an optional
911+ * 'mass flavour' that switches the computation type, the flavours are:
912+ * <br>
913+ * <ul>
914+ * <li>{@link #MolWeight} (default) - use and isotopes the natural mass
915+ * unless a specific isotope is specified</li>
916+ * <li>{@link #AverageWeight} - use and isotopes the natural mass even
917+ * if a specific isotope is specified</li>
918+ * <li>{@link #MonoIsotopic} - use and isotopes the major isotope mass
919+ * even if a specific isotope is specified</li>
920+ * <li>{@link #MostAbundant} - use the distribution of isotopes
921+ * based on their abundance and select the most abundant. For example
922+ * C<sub>6</sub>Br<sub>6</sub> would have three <sup>79</sup>Br and
923+ * <sup>81</sup>Br because their abundance is 51 and 49%.
924+ * </ul>
870925 *
871- * @param formula The IMolecularFormula to calculate
872- * @return The summed exact major isotope masses of all atoms in this MolecularFormula
926+ * @param mf molecular formula
927+ * @return the mass of the molecule
928+ * @see #MolWeight
929+ * @see #AverageWeight
930+ * @see #MonoIsotopic
931+ * @see #MostAbundant
873932 */
874- public static double getMajorIsotopeMass (IMolecularFormula formula ) {
875- double mass = 0.0 ;
876- IsotopeFactory factory ;
877- try {
878- factory = Isotopes .getInstance ();
879- } catch (IOException e ) {
880- throw new RuntimeException ("Could not instantiate the IsotopeFactory." );
881- }
882- for (IIsotope isotope : formula .isotopes ()) {
883- IIsotope major = factory .getMajorIsotope (isotope .getSymbol ());
884- if (major != null ) {
885- mass += major .getExactMass () * formula .getIsotopeCount (isotope );
933+ public static double getMass (IMolecularFormula mf ) {
934+ return getMass (mf , MolWeight );
886935 }
936+
937+ /**
938+ * @deprecated use {@link #getMass(IMolecularFormula, int)} with option
939+ * {@link #AverageWeight}.
940+ */
941+ @ Deprecated
942+ public static double getNaturalExactMass (IMolecularFormula formula ) {
943+ return getMass (formula , AverageWeight );
887944 }
888- return mass ;
945+
946+ /**
947+ * @deprecated use {@link #getMass(IMolecularFormula, int)} with option
948+ * {@link #MonoIsotopic}.
949+ */
950+ @ Deprecated
951+ public static double getMajorIsotopeMass (IMolecularFormula formula ) {
952+ return getMass (formula , MonoIsotopic );
889953 }
890954
891955 /**
@@ -960,15 +1024,17 @@ public static IMolecularFormula getMolecularFormula(IAtomContainer atomContainer
9601024 */
9611025 public static IMolecularFormula getMolecularFormula (IAtomContainer atomContainer , IMolecularFormula formula ) {
9621026 int charge = 0 ;
963- IAtom hAtom = null ;
1027+ int hcnt = 0 ;
9641028 for (IAtom iAtom : atomContainer .atoms ()) {
9651029 formula .addIsotope (iAtom );
966- if (iAtom .getFormalCharge () != null ) charge += iAtom .getFormalCharge ();
967-
968- if (iAtom .getImplicitHydrogenCount () != null && (iAtom .getImplicitHydrogenCount () > 0 )) {
969- if (hAtom == null ) hAtom = atomContainer .getBuilder ().newInstance (IAtom .class , "H" );
970- formula .addIsotope (hAtom , iAtom .getImplicitHydrogenCount ());
1030+ if (iAtom .getFormalCharge () != null )
1031+ charge += iAtom .getFormalCharge ();
1032+ if (iAtom .getImplicitHydrogenCount () != null )
1033+ hcnt += iAtom .getImplicitHydrogenCount ();
9711034 }
1035+ if (hcnt != 0 ) {
1036+ IAtom hAtom = atomContainer .getBuilder ().newInstance (IAtom .class , "H" );
1037+ formula .addIsotope (hAtom , hcnt );
9721038 }
9731039 formula .setCharge (charge );
9741040 return formula ;
@@ -1005,6 +1071,7 @@ public static IAtomContainer getAtomContainer(IMolecularFormula formula, IAtomCo
10051071 int occur = formula .getIsotopeCount (isotope );
10061072 for (int i = 0 ; i < occur ; i ++) {
10071073 IAtom atom = formula .getBuilder ().newInstance (IAtom .class , isotope );
1074+ atom .setImplicitHydrogenCount (0 );
10081075 atomContainer .addAtom (atom );
10091076 }
10101077 }
0 commit comments