def GetSystem(self, doQCMM=True, log=logFile, nbModel=None, qcModel=None):
     """Get the system with the energy model defined."""
     # . Basic setup.
     molecule = MOLFile_ToSystem(
         os.path.join(self.dataPath, self.fileName + ".mol"))
     molecule.label = self.label
     molecule.DefineMMModel(self.mmModel)
     # . Set up the QC model.
     if qcModel is not None:
         molecule.electronicState = ElectronicState(
             charge=self.qcCharge, multiplicity=self.multiplicity)
         if doQCMM:
             molecule.DefineQCModel(qcModel, qcSelection=self.qcSelection)
         else:
             molecule.DefineQCModel(qcModel)
     # . Set up the NB model.
     if (qcModel is None) or doQCMM:
         if nbModel is None: molecule.DefineNBModel(self.nbModel)
         else: molecule.DefineNBModel(nbModel)
     # . Summary.
     if LogFileActive(log):
         molecule.Summary(log=log)
         log.Paragraph("\nFormula = " + molecule.atoms.FormulaString() +
                       ".")
     # . Finish up.
     return molecule
Exemple #2
0
    def runTest(self):
        """The test."""

        # . Paths.
        dataPath = os.path.join(os.getenv("PDYNAMO_PMOLECULE"), "data", "mol")
        log = self.GetLog()

        # . Get the system.
        molecule = MOLFile_ToSystem(
            os.path.join(dataPath, "tyrosineDipeptide.mol"))
        molecule.DefineMMModel(MMModelOPLS("protein"))
        molecule.DefineNBModel(NBModelFull())
        molecule.Summary(log=log)
        molecule.Energy(log=log, doGradients=True)

        # . Save initial coordinates.
        reference3 = Clone(molecule.coordinates3)

        # . Do some dynamics.
        normalDeviateGenerator = NormalDeviateGenerator.WithRandomNumberGenerator(
            RandomNumberGenerator.WithSeed(247171))
        LangevinDynamics_SystemGeometry(
            molecule,
            collisionFrequency=25.0,
            log=log,
            logFrequency=1000,
            normalDeviateGenerator=normalDeviateGenerator,
            steps=_NSteps,
            temperature=300.0,
            timeStep=0.001)

        # . Check RMSs which should be the same as rotation and translation are removed.
        masses = molecule.atoms.GetItemAttributes("mass")
        rms0 = molecule.coordinates3.RMSDeviation(reference3, weights=masses)
        molecule.coordinates3.Superimpose(reference3, weights=masses)
        rms1 = molecule.coordinates3.RMSDeviation(reference3, weights=masses)

        # . Get the observed and reference data.
        observed = {"RMS Deviation": rms1}
        referenceData = TestDataSet("Rotation/Translation Removal")
        referenceData.AddDatum(
            TestReal("RMS Deviation",
                     rms0,
                     referenceData,
                     absoluteErrorTolerance=_RMSAbsoluteErrorTolerance,
                     toleranceFormat="{:.3f}",
                     valueFormat="{:.3f}"))

        # . Check for success/failure.
        if len(observed) > 0:
            results = referenceData.VerifyAgainst(observed)
            results.Summary(log=log, fullSummary=self.fullVerificationSummary)
            isOK = results.WasSuccessful()
        else:
            isOK = True
        self.assertTrue(isOK)
    def runTest ( self ):
        """The test."""

        # . Initialization.
        isOK         = True
        numberErrors = 0

        # . Output setup.
        dataPath = os.path.join ( os.getenv ( "PDYNAMO_PMOLECULE" ), "data", "mol" )
        log = self.GetLog ( )

        # . Get the files.
        molFiles = glob.glob ( os.path.join ( dataPath, "*.mol" ) )
        molFiles.sort ( )

        # . Loop over the files.
        for ( i, molFile ) in enumerate ( molFiles ):

            try:

                # . Get the system.
                system = MOLFile_ToSystem ( molFile )
                system.Summary ( log = log )

                # . Convert to PDB component.
                component = PDBComponent.FromSystem ( system, label = ( "{:03d}".format ( i ) ) )
                component.Summary ( log = log )

                # . Convert back to a system.
                system = component.ToSystem ( )
                system.Summary ( log = log )

                # . Finish up.
                log.Separator ( )

            # . Error.
            except Exception as e:
                numberErrors += 1
                if log is not None: log.Text ( "\nError occurred> " +  e.args[0] + "\n" )

        # . Success/failure.
        self.assertTrue ( isOK and ( numberErrors == 0 ) )
    def runTest ( self ):
        """The test."""

        # . Paths.
        dataPath = os.path.join ( os.getenv ( "PDYNAMO_ROOT" ), "molecularStructures", "aminoAcids", "mol" )
        log = self.GetLog ( )

        # . Models.
        mmModel = MMModelOPLS ( "protein" )
        nbModel = NBModelFull ( )

        # . Get all files.
        molFiles = glob.glob ( os.path.join ( dataPath, "*.mol" ) )
        molFiles.sort ( )

        # . Read all mol files.
        numberFailed = 0
        for molFile in molFiles:

            if log is not None: log.Text ( "\nProcessing " + molFile + ":\n" )
            molecule = MOLFile_ToSystem ( molFile )
            try:
                molecule.DefineMMModel ( mmModel, log = log )
                molecule.DefineNBModel ( nbModel )
                molecule.Summary ( log = log )
                molecule.Energy  ( log = log, doGradients = True )
            except Exception as e:
                numberFailed += 1
                if log is not None: log.Text ( "\nError occurred> " +  e.args[0] + "\n" )

        # . Summary of results.
        if log is not None:
            summary = log.GetSummary ( )
            summary.Start ( "OPLS Protein Parameter Tests" )
            summary.Entry ( "Successes", "{:d}".format ( len ( molFiles ) - numberFailed ) )
            summary.Entry ( "Failures" , "{:d}".format (                    numberFailed ) )
            summary.Stop  ( )

        # . Success/failure.
        self.assertTrue ( ( numberFailed == 0 ) )
    def runTest(self):
        """The test."""

        # . Paths.
        dataPath = os.path.join(os.getenv("PDYNAMO_PMOLECULE"), "data")
        molPath = os.path.join(dataPath, "mol")
        xyzPath = os.path.join(dataPath, "bAlaConformations")
        log = self.GetLog()

        # . Conformations.
        xyzFiles = glob.glob(os.path.join(xyzPath, "*.xyz"))
        xyzFiles.sort()

        # . Generate the molecule.
        molecule = MOLFile_ToSystem(os.path.join(molPath, "bAla_c7eq.mol"))
        molecule.Summary(log=log)

        # . Initialization.
        isOK = True

        # . Loop over the structures in the xyz files.
        for xyzFile in xyzFiles:
            molecule.coordinates3 = XYZFile_ToCoordinates3(xyzFile)
            if log is not None:
                conformation = os.path.split(xyzFile)[-1].split("_",
                                                                1)[-1][0:-4]
                log.Heading("bALA Configuration " + conformation,
                            QBLANKLINE=True)
            results = CIPLabelFinder(molecule, log=log)
            if results is None:
                localIsOK = False
            else:
                ((tCenters, rtCenters, stCenters, utCenters),
                 (dCenters, edCenters, zdCenters, udCenters)) = results
                localIsOK = ( len ( tCenters  ) == 4 ) and ( len ( dCenters  ) == 0 ) and \
                            ( len ( stCenters ) == 1 ) and ( len ( utCenters ) == 3 )
            isOK = (isOK and localIsOK)

        # . Success/failure.
        self.assertTrue(isOK)
    def runTest(self):
        """The test."""

        # . Paths.
        dataPath = os.path.join(os.getenv("PDYNAMO_PMOLECULE"), "data")
        molPath = os.path.join(dataPath, "mol")
        xyzPath = os.path.join(dataPath, "bAlaConformations")
        log = self.GetLog()

        # . Conformations.
        xyzFiles = glob.glob(os.path.join(xyzPath, "*.xyz"))
        xyzFiles.sort()

        # . Generate the molecule.
        molecule = MOLFile_ToSystem(os.path.join(molPath, "bAla_c7eq.mol"))
        molecule.Summary(log=log)

        # . Translate to principal axes using masses as weights.
        masses = molecule.atoms.GetItemAttributes("mass")
        molecule.coordinates3.ToPrincipalAxes(weights=masses)

        # . Loop over structures and output at the same time.
        if log is not None:
            table = log.GetTable(columns=[20, 10])
            table.Start()
            table.Title("Radii Of Gyration")
            table.Heading("Conformation")
            table.Heading("Value")
            for xyzFile in xyzFiles:
                conformation = os.path.split(xyzFile)[-1].split("_",
                                                                1)[-1][0:-4]
                coordinates3 = XYZFile_ToCoordinates3(xyzFile)
                radiusOfGyration = coordinates3.RadiusOfGyration(
                    weights=masses)
                table.Entry(conformation, alignment="left")
                table.Entry("{:.2f}".format(radiusOfGyration))
            table.Stop()

        # . Success/failure.
        self.assertTrue(True)
 def GetSystem(self, log=logFile, maximumAtoms=None):
     """Get the system with the energy model defined."""
     # . Get the QC model options.
     convergerKeywords = getattr(self, "convergerKeywords", {})
     qcModelArguments = getattr(self, "qcModelArguments", [])
     qcModelClass = getattr(self, "qcModelClass", None)
     qcModelKeywords = getattr(self, "qcModelKeywords", {})
     # . Basic setup.
     if self.fileFormat == "mol":
         molecule = MOLFile_ToSystem(
             os.path.join(self.dataPath, self.fileName + ".mol"))
     elif self.fileFormat == "xyz":
         molecule = XYZFile_ToSystem(
             os.path.join(self.dataPath, self.fileName + ".xyz"))
     molecule.electronicState = ElectronicState(
         charge=getattr(self, "charge", 0),
         multiplicity=getattr(self, "multiplicity", 1))
     molecule.label = self.label
     # . Only keep the molecule if it is not too large.
     if (maximumAtoms is None) or ((maximumAtoms is not None) and
                                   (len(molecule.atoms) <= maximumAtoms)):
         # . Define the QC model.
         if qcModelClass is not None:
             converger = DIISSCFConverger(**convergerKeywords)
             kwargs = dict(qcModelKeywords)
             kwargs["converger"] = converger
             qcModel = qcModelClass(*qcModelArguments, **kwargs)
             molecule.DefineQCModel(qcModel, log=log)
         # . Summary.
         if LogFileActive(log):
             molecule.Summary(log=log)
             log.Paragraph("\nFormula = " + molecule.atoms.FormulaString() +
                           ".")
     # . Molecule rejected.
     else:
         molecule = None
     # . Finish up.
     return molecule
    def runTest ( self ):
        """The test."""

        # . Paths.
        dataPath = os.path.join ( os.getenv ( "PDYNAMO_PMOLECULE" ), "data", "mol" )
        if self.resultPath is None: outPath  = os.path.join ( os.getenv ( "PDYNAMO_SCRATCH" ), _Destination )
        else:                       outPath  = os.path.join ( self.resultPath                , _Destination )
        if not os.path.exists ( outPath ): os.mkdir ( outPath )
        log = self.GetLog ( )

        # . Energy models.
        mmModel = MMModelOPLS ( "protein" )
        nbModel = NBModelFull ( )
        qcModel = QCModelMNDO ( converger = DIISSCFConverger ( densityTolerance = 1.0e-10 ) )

        # . Initialization.
        numberFailures = 0

        # . Loop over molecules.
        for moleculeLabel in _MoleculeLabels:

            # . Get the system.
            system = MOLFile_ToSystem ( os.path.join ( dataPath, moleculeLabel + ".mol" ) )
            if moleculeLabel in _QCModels:
                system.DefineQCModel ( qcModel )
            else:
                system.DefineMMModel ( mmModel, log = log )
                system.DefineNBModel ( nbModel )
            system.Summary ( log = log )
            system.Energy  ( log = log )

            # . Minimize well.
            LBFGSMinimize_SystemGeometry ( system,
                                           log                  =           log ,
                                           logFrequency         = _LogFrequency ,
                                           maximumIterations    =   _Iterations ,
                                           rmsGradientTolerance =    _Tolerance )

            # . Normal mode analysis.
            nmState = NormalModes_SystemGeometry ( system, log = log )

            # . Do a dynamics simulation: equilibration and then data collection.
            normalDeviateGenerator = NormalDeviateGenerator.WithRandomNumberGenerator ( RandomNumberGenerator.WithSeed ( _Seed ) )
            LangevinDynamics_SystemGeometry ( system                                          ,
                                              collisionFrequency     = _CollisionFrequency    ,
                                              log                    = log                    ,
                                              logFrequency           = _LogFrequency          ,
                                              normalDeviateGenerator = normalDeviateGenerator ,
                                              steps                  = _NSteps0               ,
                                              temperature            = _Temperature           ,
                                              timeStep               = 0.001                  )
            reference3 = Clone ( system.coordinates3 )
            trajectory = AmberTrajectoryFileWriter ( os.path.join ( outPath, moleculeLabel + ".crd" ), system )
            LangevinDynamics_SystemGeometry ( system                                          ,
                                              collisionFrequency     = _CollisionFrequency    ,
                                              log                    = log                    ,
                                              logFrequency           = _LogFrequency          ,
                                              normalDeviateGenerator = normalDeviateGenerator ,
                                              steps                  = _NSteps1               ,
                                              temperature            = _Temperature           ,
                                              timeStep               = 0.001                  ,
                                              trajectories           = [ ( trajectory, _SaveFrequency ) ] )

            # . Check RMSs.
            masses = system.atoms.GetItemAttributes ( "mass" )
            rms0   = system.coordinates3.RMSDeviation ( reference3, weights = masses )
            system.coordinates3.Superimpose ( reference3, weights = masses )
            rms1 = system.coordinates3.RMSDeviation ( reference3, weights = masses )
            if ( math.fabs ( rms1 - rms0 ) >= _RMSAbsoluteErrorTolerance ): numberFailures += 1

            # . Do a quasi-harmonic analysis.
            trajectory = AmberTrajectoryFileReader ( os.path.join ( outPath, moleculeLabel + ".crd" ), system )
            qhState    = QuasiHarmonic_SystemGeometry ( system, log = log, temperature = _Temperature, trajectories = [ trajectory ] )

        # . Success/failure.
        self.assertTrue ( ( numberFailures == 0 ) )
Exemple #9
0
    def runTest(self):
        """The test."""

        # . Paths.
        dataPath = os.path.join(os.getenv("PDYNAMO_PMOLECULE"), "data", "mol")
        log = self.GetLog()

        # . Energy models.
        mmModel = MMModelOPLS("protein")
        nbModel = NBModelFull()

        # . Get the files.
        molFiles = glob.glob(os.path.join(dataPath, "*.mol"))

        # . Initialization.
        numberErrors = 0
        numberFailures = 0

        # . Loop over the files.
        for molFile in molFiles:

            try:

                # . Get the system.
                try:
                    system = MOLFile_ToSystem(molFile)
                    system.DefineMMModel(mmModel, log=log)
                    system.DefineNBModel(nbModel)
                    system.Summary(log=log)
                except:
                    continue

                # . Calculate an energy.
                eBefore = system.Energy(log=log, doGradients=True)

                # . Define all hydrogen positions as undefined.
                for (i, atom) in enumerate(system.atoms):
                    if atom.atomicNumber == 1:
                        system.coordinates3.FlagCoordinateAsUndefined(i)

                # . Build as many undefined coordinates as possible.
                randomNumberGenerator = RandomNumberGenerator.WithSeed(957197)
                BuildHydrogenCoordinates3FromConnectivity(
                    system,
                    log=log,
                    randomNumberGenerator=randomNumberGenerator)

                # . Calculate an energy if all coordinates have been defined.
                if system.coordinates3.numberUndefined > 0:
                    numberFailures += 1
                    if log is not None:
                        log.Paragraph("Not all hydrogens have been rebuilt.")
                else:
                    eAfter = system.Energy(log=log, doGradients=True)
                    if log is not None:
                        log.Paragraph(
                            "Energy difference after rebuilding = {:.1f}.".
                            format(eAfter - eBefore))

            except Exception as e:
                numberErrors += 1
                if log is not None:
                    log.Text("\nError occurred> " + e.args[0] + "\n")

        # . Success/failure.
        self.assertTrue(((numberErrors == 0) and (numberFailures == 0)))
# . Define the solvent MM and NB models.
mmModel = MMModelOPLS ( "bookSmallExamples" )

# . Get the system.
system = Unpickle ( os.path.join ( outPath, "step7.pkl" ) )
system.Summary ( )

# . Reorient the system if necessary (see the results of GetSolvationInformation.py).
masses = system.atoms.GetItemAttributes ( "mass" )
if _Reorient: system.coordinates3.ToPrincipalAxes ( weights = masses )

# . Get the positive and negative ions.
if _NNegative > 0:
    anion = MOLFile_ToSystem ( os.path.join ( dataPath, _NegativeIon + ".mol" ) )
    anion.DefineMMModel ( mmModel )
    anion.Summary ( )
if _NPositive > 0:
    cation = MOLFile_ToSystem ( os.path.join ( dataPath, _PositiveIon + ".mol" ) )
    cation.DefineMMModel ( mmModel )
    cation.Summary ( )

# . Add the counterions.
newSystem = AddCounterIons ( system, _NNegative, anion, _NPositive, cation, ( _XBox, _YBox, _ZBox ) )

# . Save the combined system.
newSystem.configuration.Clear ( )
Pickle ( os.path.join ( outPath, "step8_a.pkl" ), newSystem )

# . Print PDB file.
PDBFile_FromSystem ( os.path.join ( outPath, "step8_a.pdb" ), newSystem )
    def runTest(self):
        """The test."""

        # . Output setup.
        dataPath = os.path.join(os.getenv("PDYNAMO_PMOLECULE"), "data", "mol")
        log = self.GetLog()

        # . Define the MM, NB and QC models.
        mmModel = MMModelOPLS("bookSmallExamples")
        nbModel = NBModelFull()
        qcModel = QCModelMNDO()

        # . Define the dimer with an MM model.
        dimer = MOLFile_ToSystem(os.path.join(dataPath, "waterDimer_cs.mol"))
        dimer.DefineMMModel(mmModel)
        dimer.Summary(log=log)

        # . Define the monomer selections.
        selection1 = Selection.FromIterable(range(0, 3))
        selection2 = Selection.FromIterable(range(3, 6))

        # . Get the monomer energies.
        e1 = self.MonomerEnergies(dimer, selection1, nbModel, qcModel, log=log)
        e2 = self.MonomerEnergies(dimer, selection2, nbModel, qcModel, log=log)

        # . Get the binding energies.
        e12 = {}
        for model1 in _Models:
            for model2 in _Models:
                key = model1 + " " + model2
                if log is not None:
                    log.Heading(model1 + "/" + model2 + " Dimer Calculation",
                                QBLANKLINE=True)
                # . Define the energy model.
                if key == "QC QC": dimer.DefineQCModel(qcModel)
                elif key == "QC MM":
                    dimer.DefineQCModel(qcModel, qcSelection=selection1)
                elif key == "MM QC":
                    dimer.DefineQCModel(qcModel, qcSelection=selection2)
                else:
                    dimer.energyModel.ClearQCModel(dimer.configuration)
                if "MM" in key: dimer.DefineNBModel(nbModel)
                dimer.Summary(log=log)
                # . Store the results.
                e12[key] = dimer.Energy(log=log) - e1[model1] - e2[model2]

        # . Output the results.
        if log is not None:
            keys = e12.keys()
            keys.sort()
            table = log.GetTable(columns=[20, 20, 20])
            table.Start()
            table.Title("Water Dimer Binding Energies")
            table.Heading("Monomer 1")
            table.Heading("Monomer 2")
            table.Heading("Binding Energy")
            for key in keys:
                (model1, model2) = key.split()
                table.Entry(model1)
                table.Entry(model2)
                table.Entry("{:.1f}".format(e12[key]))
            table.Stop()

        # . Success/failure.
        isOK = True
        for e in e12.values():
            if (e < _LowerBound) or (e > _UpperBound):
                isOK = False
                break
        self.assertTrue(isOK)
#   takes no (interesting) arguments.
#
# . Note on scratch names:
#
#   It has been noticed that ORCA itself can give an error when the name of the scratch directory is too long.
#   This occurs in the "%pcname" line of the ORCA input file. To cure this use a shorter name - either by resetting
#   the environment variable PDYNAMO_SCRATCH or by explicitly passing a name to the model with the "scratch" option.
#

# . Define the MM, NB and QC models.
mmModel = MMModelOPLS("bookSmallExamples")
nbModel = NBModelORCA()
qcModel = QCModelORCA("MP2:6-31G*", "EXTREMESCF", "SCFCONV10")

# . Define the molecule.
molecule = MOLFile_ToSystem(
    os.path.join(os.getenv("PDYNAMO_PMOLECULE"), "data", "mol",
                 "waterDimer_cs.mol"))

# . Define the selection for the first molecule.
firstWater = Selection.FromIterable([0, 1, 2])

# . Define the energy model.
molecule.DefineMMModel(mmModel)
molecule.DefineQCModel(qcModel, qcSelection=firstWater)
molecule.DefineNBModel(nbModel)
molecule.Summary()

# . Calculate an energy.
molecule.Energy(doGradients=True)
Exemple #13
0
    def runTest(self):
        """The test."""

        # . Initialization.
        dataPath = os.path.join(os.getenv("PDYNAMO_PMOLECULE"), "data", "mol")
        log = self.GetLog()
        translation = Vector3.Uninitialized()

        # . Get the individual systems.
        energies = []
        molecules = []
        for (i, label) in enumerate(_Molecules):
            molecule = MOLFile_ToSystem(os.path.join(dataPath, label + ".mol"))
            molecule.label = label
            molecule.DefineMMModel(_mmModel)
            molecule.DefineNBModel(_nbModel)
            molecule.Summary(log=log)
            molecule.coordinates3.TranslateToCenter()
            molecule.configuration.Clear()
            energies.append(molecule.Energy(log=log, doGradients=True))
            molecules.append(molecule)

        # . Data initialization.
        observed = {}
        referenceData = TestDataSet("Merge/Prune Energies")

        # . Loop over the tests.
        for (testIndex, (moleculeFrequencies,
                         moleculePruneIndices)) in enumerate(_Tests):

            # . Heading.
            if log is not None:
                log.Heading("Merge/Prune Test {:d}".format(testIndex),
                            QBLANKLINE=True)

            # . Initialization.
            mergedEnergy = 0.0
            prunedEnergy = 0.0
            translation.Set(0.0)

            # . Gather items.
            index = 0
            numberAtoms = 0
            pruneIndices = []
            toMerge = []
            for (i, frequency) in enumerate(moleculeFrequencies):
                molecule = molecules[i]
                mergedEnergy += energies[i] * frequency
                for f in range(frequency):
                    cloned = Clone(molecule)
                    translation[0] += _Displacement
                    cloned.coordinates3.Translate(translation)
                    toMerge.append(cloned)
                    if index in moleculePruneIndices:
                        pruneIndices.extend(
                            range(numberAtoms,
                                  numberAtoms + len(cloned.atoms)))
                        prunedEnergy += energies[i]
                    index += 1
                    numberAtoms += len(cloned.atoms)

            # . Merging.
            merged = toMerge[0].Merge(toMerge[1:])
            merged.Summary(log=log)
            eMerged = merged.Energy(log=log)

            # . Pruning.
            pruned = merged.Prune(Selection.FromIterable(pruneIndices))
            pruned.Summary(log=log)
            ePruned = pruned.Energy(log=log)

            # . Get the observed and reference data.
            for (tag, eObserved,
                 eReference) in (("Merged Energy {:d}".format(testIndex),
                                  eMerged, mergedEnergy),
                                 ("Pruned Energy {:d}".format(testIndex),
                                  ePruned, prunedEnergy)):
                observed[tag] = eObserved
                referenceData.AddDatum(
                    TestReal(
                        tag,
                        eReference,
                        referenceData,
                        absoluteErrorTolerance=_EnergyAbsoluteErrorTolerance,
                        toleranceFormat="{:.3f}",
                        valueFormat="{:.3f}"))

        # . Finish up.
        if log is not None: log.Separator()

        # . Check for success/failure.
        if len(observed) > 0:
            results = referenceData.VerifyAgainst(observed)
            results.Summary(log=log, fullSummary=self.fullVerificationSummary)
            isOK = results.WasSuccessful()
        else:
            isOK = True

        # . Success/failure.
        self.assertTrue(isOK)
    def runTest(self):
        """The test."""

        # . Initialization.
        isOK = True
        log = self.GetLog()
        molPath = os.path.join(os.getenv("PDYNAMO_PMOLECULE"), "data", "mol")

        # . Options.
        converger = DIISSCFConverger(densityTolerance=1.0e-6,
                                     maximumSCFCycles=500)
        qcModel = QCModelMNDO("am1",
                              converger=converger,
                              isSpinRestricted=False)
        singlet = ElectronicState(charge=1, multiplicity=1)
        triplet = ElectronicState(charge=1, multiplicity=3)

        # . Optimizer.
        optimizer = QuasiNewtonMinimizer(logFrequency=1,
                                         maximumIterations=500,
                                         rmsGradientTolerance=0.05)
        optimizer.Summary(log=log)

        # . Set up the system.
        system = MOLFile_ToSystem(os.path.join(molPath, "phenylCation.mol"))
        system.electronicState = singlet
        system.label = "Phenyl Cation"
        system.DefineQCModel(qcModel)
        system.Summary(log=log)

        # . Check both methods.
        numberNotConverged = 0
        results = {}
        for method in ("GP", "PF"):

            # . Reset coordinates.
            system.coordinates3 = MOLFile_ToCoordinates3(
                os.path.join(molPath, "phenylCation.mol"))
            system.configuration.Clear()

            # . Set up the objective function.
            seamOF = SEAMObjectiveFunction.FromSystem(system,
                                                      singlet,
                                                      triplet,
                                                      method=method)
            #seamOF.RemoveRotationTranslation ( )

            # . Minimize.
            #seamOF.TestGradients ( delta = 1.0e-05 ) # . Works with 1.0e-10 density tolerance.
            cpu = CPUTime()
            report = optimizer.Iterate(seamOF, log=log)
            report["CPU Time"] = cpu.CurrentAsString()

            # . Final energies.
            (f1, f2) = seamOF.Energies(doGradients=True, log=log)
            report["Energy 1"] = f1
            report["Energy 2"] = f2
            results[method] = report
            if not report.get("Converged", False): numberNotConverged += 1

        # . Print out a summary of the results.
        if LogFileActive(log):
            table = log.GetTable(columns=[10, 20, 20, 10, 10, 20])
            table.Start()
            table.Title("Surface Crossing Optimizations")
            table.Heading("Method")
            table.Heading("State Energies", columnSpan=2)
            table.Heading("Converged")
            table.Heading("Calls")
            table.Heading("Time")
            for method in ("GP", "PF"):
                report = results[method]
                table.Entry(method, alignment="left")
                table.Entry("{:20.1f}".format(report["Energy 1"]))
                table.Entry("{:20.1f}".format(report["Energy 2"]))
                table.Entry("{!r}".format(report.get("Converged", False)))
                table.Entry("{:d}".format(report["Function Calls"]))
                table.Entry(report["CPU Time"])
            table.Stop()

        # . Finish up.
        self.assertTrue(numberNotConverged == 0)