def SteepestDescentPath_SystemGeometry ( system , fromSaddle = True , functionStep = 0.2 , logFrequency = 1 , maximumIterations = 50 , pathStep = 0.025 , useMassWeighting = False , saveFrequency = 0 , trajectory = None , log = logFile ): """Determine a steepest descent path.""" # . Create an object function. of = SystemGeometryObjectiveFunction.FromSystem ( system ) if useMassWeighting: of.DefineWeights ( ) of.RemoveRotationTranslation ( ) # . Define trajectories. if ( saveFrequency > 0 ) and ( saveFrequency < maximumIterations ) and ( trajectory is not None ): of.DefineTrajectory ( trajectory, saveFrequency ) # . Set up the iterator. optimizer = SteepestDescentPathFinder ( fromSaddle = fromSaddle , functionStep = functionStep , logFrequency = logFrequency , maximumIterations = maximumIterations , pathStep = pathStep ) optimizer.Summary ( log = log ) # . Iterate. return optimizer.Iterate ( of, log = log )
def _SetUpOptimization(system, defaultOptions, defaultsToChange, inputOptions, removeRotationTranslation): """Generic function to set up an optimization.""" # . Get default options - overridden with more suitable values if necessary. options = dict(defaultOptions) options.update({ "logFrequency": 1, "maximumIterations": 50, "rmsGradientTolerance": 1.5 }) options.update(defaultsToChange) # . Update with the input options. options.update(inputOptions) # . Get some non-optimizer options. log = options.pop("log", logFile) optimizeSymmetryParameters = options.pop("optimizeSymmetryParameters", False) trajectories = options.pop("trajectories", []) # . Set up the objective function. of = SystemGeometryObjectiveFunction.FromSystem(system) if removeRotationTranslation: of.RemoveRotationTranslation() if optimizeSymmetryParameters: of.IncludeSymmetryParameters() for (trajectory, saveFrequency) in trajectories: of.DefineTrajectory(trajectory, saveFrequency) # . Finish up. return (of, options, log)
def _SetUpSimulation ( system, defaultOptions, defaultsToChange, inputOptions ): """Generic function to set up an optimization.""" # . Get default options - overridden with more suitable values if necessary. options = dict ( defaultOptions ) options.update ( { "logFrequency" : 1, "steps" : 1000, "timeStep" : 0.001 } ) options.update ( defaultsToChange ) # . Update with the input options. options.update ( inputOptions ) # . Change steps to maximumIterations. options["maximumIterations"] = options.pop ( "steps" ) # . Get some non-optimizer options. log = options.pop ( "log" , logFile ) removeRotationTranslation = options.pop ( "removeRotationTranslation" , True ) trajectories = options.pop ( "trajectories" , [] ) # . Set up the objective function. of = SystemGeometryObjectiveFunction.FromSystem ( system ) of.DefineWeights ( ) if removeRotationTranslation: of.RemoveRotationTranslation ( ) for ( trajectory, saveFrequency ) in trajectories: of.DefineTrajectory ( trajectory, saveFrequency ) # . Finish up. return ( of, options, log )
def __init__ ( self, system, trajectory, **keywordArguments ): """Constructor.""" # . Set defaults for all options. for ( key, value ) in self.__class__.attributes.iteritems ( ): setattr ( self, key, value ) # . Set values of keyword arguments. for ( key, value ) in keywordArguments.iteritems ( ): setattr ( self, key, value ) # . Define the system geometry object function. self.objectiveFunction = SystemGeometryObjectiveFunction.FromSystem ( system ) # . Define the trajectory - a check should be made here to ensure that the trajectory is a direct access one with coordinates! # . Reading and writing the header/footer is not required but maybe should be included for completeness? self.trajectory = trajectory # . Get some scratch space. self.g = Real1DArray.WithExtent ( self.objectiveFunction.NumberOfVariables ( ) ) self.gd = Real1DArray.WithExtent ( self.objectiveFunction.NumberOfVariables ( ) + self.NumberOfVariables ( ) ) self.x = Real1DArray.WithExtent ( self.objectiveFunction.NumberOfVariables ( ) ) self.x0 = Real1DArray.WithExtent ( self.objectiveFunction.NumberOfVariables ( ) ) self.xn = Real1DArray.WithExtent ( self.objectiveFunction.NumberOfVariables ( ) ) self.y = Real1DArray.WithExtent ( self.objectiveFunction.NumberOfVariables ( ) ) self.g.Set ( 0.0 ) self.gd.Set ( 0.0 ) self.x.Set ( 0.0 ) self.x0.Set ( 0.0 ) self.xn.Set ( 0.0 ) self.y.Set ( 0.0 ) # . Get the first structure on the trajectory. self.trajectory.RestoreOwnerData ( index = 0 ) self.objectiveFunction.VariablesGet ( self.x0 ) # . Make the first structure the reference structure. # . It is assumed that the remaining structures on the trajectory are already # . orientated with respect to this one. This is the case for trajectories # . from linear-interpolation or expansion or previous SAW calculations but # . may not be otherwise. if self.removeRotationTranslation: self.objectiveFunction.RemoveRotationTranslation ( reference = self.objectiveFunction.system.coordinates3 ) # . Get the last structure on the trajectory. self.trajectory.RestoreOwnerData ( index = self.trajectory.frames - 1 ) self.objectiveFunction.VariablesGet ( self.xn ) self.trajectories = []
def runTest ( self ): """The test.""" # . Initialization. log = self.GetLog ( ) if self.checkEnergies: energyDifferences = {} if self.geometryOptimize: optimizationResults = {} self.optimizer.Summary ( log = log ) if self.testGradients: maximumGradientDeviation = 0.0 # . Loop over the molecules. numberEnergyFailures = 0 for testSystem in self.crystalTestSystems: # . Get the molecule. molecule = testSystem.GetSystem ( doQCMM = self.doQCMM, doQCQC = self.doQCQC, log = log, qcModel = self.qcModel, useSymmetry = self.useSymmetry ) # . Analyze the transformations. CrystalAnalyzeTransformations ( molecule, log = log ) # . Calculate the energy and check it. try: energy = molecule.Energy ( log = log, doGradients = True ) energyOK = True if self.checkEnergies: if self.useSymmetry: energyDifferences[molecule.label] = math.fabs ( energy - testSystem.p1Factor * testSystem.crystalEnergy ) else: energyDifferences[molecule.label] = math.fabs ( energy - testSystem.vacuumEnergy ) except: energyOK = False numberEnergyFailures += 1 if log is not None: log.Paragraph ( "Error calculating initial energy." ) # . Skip if not OK. if not energyOK: continue # . Test the gradients. # . The gradients are definitely more sensitive to the finite-difference step when using fractional coordinates. if self.testGradients: of = SystemGeometryObjectiveFunction.FromSystem ( molecule ) of.IncludeSymmetryParameters ( ) deviation = of.TestGradients ( delta = 5.0e-6, log = log, tolerance = 3.0e-4 ) maximumGradientDeviation = max ( maximumGradientDeviation, deviation ) # . Geometry optimize. if self.geometryOptimize and ( ( self.qcModel is None ) or ( self.doQCMM ) or ( self.doQCQC ) or ( ( self.qcModel is not None ) and ( testSystem.canQCOptimize ) ) ): # . Save the symmetry parameters for later. if self.useSymmetry: spInitial = molecule.symmetry.crystalClass.GetUniqueSymmetryParameters ( molecule.configuration.symmetryParameters ) of = SystemGeometryObjectiveFunction.FromSystem ( molecule ) if self.useSymmetry: of.IncludeSymmetryParameters ( ) state = self.optimizer.Iterate ( of, log = log ) finalEnergy = molecule.Energy ( log = log, doGradients = True ) optimizationResults[molecule.label] = { "Initial Energy" : energy, "Final Energy" : finalEnergy, "Function Calls" : state["Function Calls"], "Converged" : state["Converged"] } if self.useSymmetry: spFinal = molecule.symmetry.crystalClass.GetUniqueSymmetryParameters ( molecule.configuration.symmetryParameters ) optimizationResults[molecule.label].update ( { "Initial Parameters" : spInitial, "Final Parameters" : spFinal } ) # . Results. # . Energy differences. if self.checkEnergies and ( log is not None ): # . System labels. labels = energyDifferences.keys ( ) labels.sort ( ) # . Header. table = log.GetTable ( columns = [ 30, 20 ] ) table.Start ( ) if self.useSymmetry: table.Title ( "Differences in Crystal Energies" ) else: table.Title ( "Differences in Vacuum Energies" ) table.Heading ( "System" ) table.Heading ( "Difference" ) # . Data for label in labels: table.Entry ( label, alignment = "left" ) table.Entry ( "{:20.4f}".format ( energyDifferences[label] ) ) table.Stop ( ) # . Optimizations. if self.geometryOptimize: self.GeometryOptimizationSummary ( optimizationResults, log = log ) # . Get the observed and reference data. observed = {} referenceData = TestDataSet ( "Crystal Energies" ) if self.checkEnergies: observed.update ( energyDifferences ) for label in energyDifferences: referenceData.AddDatum ( TestReal ( label, 0.0, referenceData, absoluteErrorTolerance = _EnergyTolerance, toleranceFormat = "{:.3f}", valueFormat = "{:.3f}" ) ) if self.testGradients: observed["Gradient Error"] = maximumGradientDeviation referenceData.AddDatum ( TestReal ( "Gradient Error", 0.0, referenceData, absoluteErrorTolerance = _GradientAbsoluteErrorTolerance, 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 isOK = isOK and ( numberEnergyFailures == 0 ) self.assertTrue ( isOK )
def runTest(self): """The test.""" # . Initialization. log = self.GetLog() numberErrors = 0 if self.testGradients: maximumGradientDeviation = 0.0 # . Loop over systems and QC models. labels = self.qcmmTestSystems.keys() labels.sort() for label in labels: testSystem = self.qcmmTestSystems[label] for qcModel in self.qcModels[label]: # . Get the molecule. molecule = testSystem.GetSystem(log=log, qcModel=qcModel) # . Energy. try: energy = molecule.Energy(log=log, doGradients=True) # . Charges. charges = molecule.AtomicCharges() charges.Print(log=log, title="Charges") if log is not None: log.Paragraph("Total Charge = {:.3f}".format( sum(charges))) charges = molecule.AtomicCharges(spinDensities=True) charges.Print(log=log, title="Spin Densities") if log is not None: log.Paragraph("Total Spin Density = {:.3f}".format( sum(charges))) # . Gradient testing. if self.testGradients and (len(molecule.atoms) < self.maximumAtoms): of = SystemGeometryObjectiveFunction.FromSystem( molecule) gradientDeviation = of.TestGradients(delta=1.0e-06, log=log, tolerance=1.0e-03) maximumGradientDeviation = max( maximumGradientDeviation, gradientDeviation) # . Error. except Exception as e: numberErrors += 1 if log is not None: log.Text("\nError occurred> " + e.args[0] + "\n") # . Get the observed and reference data. observed = {} referenceData = TestDataSet("MNDO CI QC/MM Energies") if self.testGradients: observed["Gradient Error"] = maximumGradientDeviation referenceData.AddDatum( TestReal( "Gradient Error", 0.0, referenceData, absoluteErrorTolerance=_GradientAbsoluteErrorTolerance, 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 isOK = isOK and (numberErrors == 0) self.assertTrue(isOK)
def runTest(self): """The test.""" # . Initialization. if self.generateReferenceData: referenceData = TestDataSet("AMBER Test") else: observed = {} # . Output setup. dataPath = os.path.join(os.getenv("PDYNAMO_PBABEL"), "data", "amber") log = self.GetLog() # . Models. nbModel = NBModelFull() # . Loop over the molecules. for label in _SystemLabels: # . Read the data. molecule = AmberTopologyFile_ToSystem(os.path.join( dataPath, label + ".top"), log=log) molecule.coordinates3 = AmberCrdFile_ToCoordinates3(os.path.join( dataPath, label + ".crd"), log=log) # . Calculation. molecule.DefineNBModel(nbModel) molecule.Summary(log=log) if log is not None: log.Text("\nFormula = " + molecule.atoms.FormulaString() + ".\n") energy = molecule.Energy(doGradients=True, log=log) # . Get the dictionary of energies. localObserved = molecule.configuration.energyTerms.Terms( asDictionary=True) localObserved["Potential Energy"] = energy # . Test the gradients. if len(molecule.atoms) <= _MaximumAtoms: of = SystemGeometryObjectiveFunction.FromSystem(molecule) localObserved["Gradient Error"] = of.TestGradients(log=log) # . Generate reference data. if self.generateReferenceData: localData = TestDataSet(label, parent=referenceData) for (key, value) in localObserved.iteritems(): if key == "Gradient Error": localData.AddDatum( TestReal(key, value, localData, absoluteErrorTolerance= _GradientAbsoluteErrorTolerance)) else: localData.AddDatum( TestReal( key, value, localData, absoluteErrorTolerance=_AbsoluteErrorTolerance, toleranceFormat="{:.3f}", valueFormat="{:.3f}")) referenceData.AddDatum(localData) # . Accumulate observed data. else: observed[label] = localObserved # . Generate the reference data. if self.generateReferenceData: referenceData.Summary(log=log) Pickle(self.referenceDataPath, referenceData) isOK = True # . Verify the observed data against the reference data. else: referenceData = Unpickle(self.referenceDataPath) results = referenceData.VerifyAgainst(observed) results.Summary(log=log, fullSummary=self.fullVerificationSummary) isOK = results.WasSuccessful() # . Success/failure. self.assertTrue(isOK)
def runTest(self): """The test.""" # . Initialization. log = self.GetLog() modelResults = {} numberEnergyTests = 0 numberErrors = 0 numberGradientTests = 0 if self.testGradients: maximumGradientDeviation = 0.0 # . Energy data. if self.generateReferenceData: referenceData = TestDataSet("MNDO RHF Energies") energyDataSets = {} for model in self.modelLabels: energyDataSet = TestDataSet(model, parent=referenceData) energyDataSets[model] = energyDataSet referenceData.AddDatum(energyDataSet) else: energyResults = {} # . Loop over systems. for testSystem in self.testSystems: # . Get results (if necessary). modelLabel = testSystem.modelLabel if not self.generateReferenceData: energies = energyResults.get(modelLabel, None) if energies is None: energies = {} energyResults[modelLabel] = energies results = modelResults.get(modelLabel, None) if results is None: results = {} modelResults[modelLabel] = results cycles = results.get("Cycles", None) if cycles is None: cycles = [] results["Cycles"] = cycles # . Get the molecule. try: molecule = testSystem.GetSystem( log=log, maximumAtoms=self.maximumEnergyAtoms) except: molecule = None results["Undefined"] = results.get("Undefined", 0) + 1 if molecule is None: continue # . Determine an energy. try: try: e = molecule.Energy(log=log, doGradients=True) i = molecule.configuration.qcState.GetItem("SCF Cycles") results["Converged"] = results.get("Converged", 0) + 1 cycles.append(float(i)) # . Generate reference data - converged only. if self.generateReferenceData: energyDataSet = energyDataSets[modelLabel] energyDataSet.AddDatum( TestReal( molecule.label, e, energyDataSet, absoluteErrorTolerance=_AbsoluteErrorTolerance, toleranceFormat="{:.3f}", valueFormat="{:.3f}")) # . Accumulate observed data. else: energies[molecule.label] = e except Exception as e: results["Not Converged"] = results.get("Not Converged", 0) + 1 # . Bond orders. labels = [] for i in range(len(molecule.atoms)): labels.append(molecule.atoms[i].path) (bondOrders, charges, freevalence, totalvalence) = molecule.energyModel.qcModel.BondOrders( molecule.configuration) bondOrders.PrintWithCondition( (lambda x, i, j: (i != j) and (math.fabs(x) >= _BondOrderTolerance)), itemFormat="{:.3f}", labels=labels, log=log, title="Bond Orders") # . Charges. charges = molecule.AtomicCharges() charges.Print(log=log, title="Charges") if log is not None: log.Paragraph("Total Charge = {:.3f}".format(sum(charges))) charges = molecule.AtomicCharges(spinDensities=True) charges.Print(log=log, title="Spin Densities") if log is not None: log.Paragraph("Total Spin Density = {:.3f}".format( sum(charges))) # . Dipole moment. dipole = molecule.DipoleMoment() dipole.Print(log=log, title="Dipole") # . Gradient testing. if self.testGradients and (len( molecule.atoms) < self.maximumGradientAtoms) and ( numberGradientTests < self.maximumGradientTests): of = SystemGeometryObjectiveFunction.FromSystem(molecule) gradientDeviation = of.TestGradients(log=log) maximumGradientDeviation = max(maximumGradientDeviation, gradientDeviation) numberGradientTests += 1 # . Error. except Exception as e: numberErrors += 1 if log is not None: log.Text("\nError occurred> " + e.args[0] + "\n") # . Check the number of tests. numberEnergyTests += 1 if numberEnergyTests >= self.maximumEnergyTests: break # . Print model results. if log is not None: models = modelResults.keys() models.sort() table = log.GetTable(columns=7 * [_TableModelWidth]) table.Start() table.Title("Model Results") table.Heading("Model") table.Heading("Undefined") table.Heading("Not Converged") table.Heading("Converged") table.Heading("<Cycles>") table.Heading("Max. Cycles") table.Heading("Min. Cycles") for model in models: results = modelResults[model] cycles = Statistics(results["Cycles"]) table.Entry(model, alignment="left") table.Entry("{:d}".format(results.get("Undefined", 0))) table.Entry("{:d}".format(results.get("Not Converged", 0))) table.Entry("{:d}".format(results.get("Converged", 0))) if cycles.size > 0: table.Entry("{:.1f}".format(cycles.mean)) table.Entry("{:.0f}".format(cycles.maximum)) table.Entry("{:.0f}".format(cycles.minimum)) else: table.Entry("-") table.Entry("-") table.Entry("-") table.Stop() # . Energy data. # . Generate the reference data. if self.generateReferenceData: referenceData.Summary(log=log) Pickle(self.referenceDataPath, referenceData) isOK = True # . Verify the observed data against the reference data. else: referenceData = Unpickle(self.referenceDataPath) results = referenceData.VerifyAgainst(energyResults) results.Summary(log=log, fullSummary=self.fullVerificationSummary) isOK = results.WasSuccessful() # . Gradient data set. if self.testGradients: # . Get the observed and reference data. observed = {} referenceData = TestDataSet("MNDO RHF Gradients") observed["Gradient Error"] = maximumGradientDeviation referenceData.AddDatum( TestReal( "Gradient Error", 0.0, referenceData, absoluteErrorTolerance=_GradientAbsoluteErrorTolerance, toleranceFormat="{:.3f}", valueFormat="{:.3f}")) # . Check for success/failure. if len(observed) > 0: results = referenceData.VerifyAgainst(observed) results.Summary(log=log, fullSummary=self.fullVerificationSummary) isOK = isOK and results.WasSuccessful() # . Finish up. isOK = isOK and (numberErrors == 0) self.assertTrue(isOK)
def runTest(self): """The test.""" # . Initialization. if self.generateReferenceData: referenceData = TestDataSet("Charmm Test") else: observed = {} # . Output setup. dataPath = os.path.join(os.getenv("PDYNAMO_PBABEL"), "data", "charmm") outPath = None if self.resultPath is not None: outPath = os.path.join(self.resultPath, "pdb") if not os.path.exists(outPath): os.mkdir(outPath) log = self.GetLog() # . Get the parameters. parameterPaths = [] for parameterPath in _ParameterPaths: parameterPaths.append( os.path.join(dataPath, parameterPath + ".prm")) parameters = CHARMMParameterFiles_ToParameters(parameterPaths, log=log) # . Generate systems. for label in _SystemLabels: if log is not None: log.Text("\n" + (80 * "=") + "\n") log.Text(label + "\n") log.Text(80 * "=" + "\n") system = CHARMMPSFFile_ToSystem(os.path.join( dataPath, label + ".psfx"), isXPLOR=True, parameters=parameters, log=log) system.coordinates3 = CHARMMCRDFile_ToCoordinates3(os.path.join( dataPath, label + ".chm"), log=log) system.label = label system.DefineNBModel(NBModelFull()) system.Summary(log=log) energy = system.Energy(log=log) log.Text("\nEnergy (kcal/mole) = {:.4f}\n".format( energy / UNITS_ENERGY_KILOCALORIES_PER_MOLE_TO_KILOJOULES_PER_MOLE)) # . Get the dictionary of energies. localObserved = system.configuration.energyTerms.Terms( asDictionary=True) localObserved["Potential Energy"] = energy # . Test gradients. if len(system.atoms) <= _MaximumAtoms: of = SystemGeometryObjectiveFunction.FromSystem(system) of.TestGradients(log=log) localObserved["Gradient Error"] = of.TestGradients(log=log) # . Write PDB file and do various sequence tests. if not self.generateReferenceData: if outPath is not None: PDBFile_FromSystem(os.path.join(outPath, label + ".pdb"), system, useSegmentEntityLabels=True) system.sequence.PrintComponentSequence(log=log) log.Text("\nSelections:\n\n") for pattern in _Patterns[label]: log.Text("{:<30s} {:5d}\n".format( pattern, len(AtomSelection.FromAtomPattern(system, pattern)))) # . Generate reference data. if self.generateReferenceData: localData = TestDataSet(label, parent=referenceData) for (key, value) in localObserved.iteritems(): if key == "Gradient Error": localData.AddDatum( TestReal(key, value, localData, absoluteErrorTolerance= _GradientAbsoluteErrorTolerance)) else: localData.AddDatum( TestReal( key, value, localData, absoluteErrorTolerance=_AbsoluteErrorTolerance, toleranceFormat="{:.3f}", valueFormat="{:.3f}")) referenceData.AddDatum(localData) # . Accumulate observed data. else: observed[label] = localObserved # . Generate the reference data. if self.generateReferenceData: referenceData.Summary(log=log) Pickle(self.referenceDataPath, referenceData) isOK = True # . Verify the observed data against the reference data. else: referenceData = Unpickle(self.referenceDataPath) results = referenceData.VerifyAgainst(observed) results.Summary(log=log, fullSummary=self.fullVerificationSummary) isOK = results.WasSuccessful() # . Success/failure. self.assertTrue(isOK)
def runTest(self): """The test.""" # . Initialization. observed = {} gromacsReference = True # . We have two references: One for energies obtained with Gromacs; another for pDynamo energies if gromacsReference: referenceDataPath = os.path.join( os.getenv("PDYNAMO_PBABEL"), "data", "reference/GromacsTopCrdRead_gromacsValues.pkl") else: referenceDataPath = os.path.join( os.getenv("PDYNAMO_PBABEL"), "data", "reference/GromacsTopCrdRead_pDynamoValues.pkl") # . Output setup. dataPath = os.path.join(os.getenv("PDYNAMO_PBABEL"), "data", "gromacs") outPath = None self.resultPath = dataPath if self.resultPath is not None: outPath = os.path.join(self.resultPath, "pdb") if not os.path.exists(outPath): os.mkdir(outPath) log = self.GetLog() # . Generate systems. for label in _SystemLabels: # . Force field. for ff in _ForceFields: # . Header. if log is not None: log.Text("\n" + (120 * "=") + "\n") log.Text(label + "-" + ff + "\n") log.Text(120 * "=" + "\n") # . Get the parameters. filename = os.path.join(dataPath, label + "_" + ff) parameters = GromacsParameters_ToParameters(filename + ".top", log=log) system = GromacsDefinitions_ToSystem(filename + ".top", parameters=parameters, log=log) system.coordinates3 = GromacsCrdFile_ToCoordinates3(filename + ".gro", log=log) system.label = label if hasattr(system.configuration, "symmetryParameters"): system.DefineNBModel(NBModelABFS(**ABFS_options)) else: system.DefineNBModel(NBModelFull()) system.Summary(log=log) energy = system.Energy(log=log) log.Text("\nEnergy (kcal/mole) = {:.4f}\n".format( energy / UNITS_ENERGY_KILOCALORIES_PER_MOLE_TO_KILOJOULES_PER_MOLE)) # . Get the dictionary of energies. localObserved = system.configuration.energyTerms.Terms( asDictionary=True) localObserved["Potential Energy"] = energy # . U-B term in Gromacs includes harmonic angle contribution, but not in pDynamo. Their sum should be equal, though. if gromacsReference and (ff == "CHARMM"): localObserved["Harmonic Angle + U-B"] = localObserved[ "Harmonic Angle"] + localObserved["Urey-Bradley"] del localObserved["Harmonic Angle"] del localObserved["Urey-Bradley"] # . Test gradients. if len(system.atoms) <= _MaximumAtoms: of = SystemGeometryObjectiveFunction.FromSystem(system) of.TestGradients(log=log) localObserved["Gradient Error"] = of.TestGradients(log=log) # . Write PDB file if outPath is not None: PDBFile_FromSystem(os.path.join(outPath, label + ".pdb"), system) # . Accumulate current data dataLabel = label + "-" + ff observed[dataLabel] = localObserved # . Verify the observed data against the reference data. referenceData = Unpickle(referenceDataPath) results = referenceData.VerifyAgainst(observed) isOK = results.WasSuccessful() results.Summary(log=log, fullSummary=True) # . Success/failure. self.assertTrue(isOK)
def runTest(self): """The test.""" # . Initialization. log = self.GetLog() numberErrors = 0 if self.testGradients: maximumGradientDeviation = 0.0 # . Loop over systems. for testSystem in self.testSystems: # . Get the molecule. molecule = testSystem.GetSystem( log=log, maximumAtoms=self.maximumEnergyAtoms) if molecule is None: continue # . Determine an energy. try: energy = molecule.Energy(log=log, doGradients=True) # . Bond orders. labels = [] for i in range(len(molecule.atoms)): labels.append(molecule.atoms[i].path) (bondOrders, charges, freevalence, totalvalence) = molecule.energyModel.qcModel.BondOrders( molecule.configuration) bondOrders.PrintWithCondition( (lambda x, i, j: (i != j) and (math.fabs(x) >= _BondOrderTolerance)), itemFormat="{:.3f}", labels=labels, log=log, title="Bond Orders") # . Charges. charges = molecule.AtomicCharges() charges.Print(log=log, title="Charges") if log is not None: log.Paragraph("Total Charge = {:.3f}".format(sum(charges))) charges = molecule.AtomicCharges(spinDensities=True) charges.Print(log=log, title="Spin Densities") if log is not None: log.Paragraph("Total Spin Density = {:.3f}".format( sum(charges))) # . Dipole moment. dipole = molecule.DipoleMoment() dipole.Print(log=log, title="Dipole") # . Gradient testing. if self.testGradients and (len(molecule.atoms) < self.maximumGradientAtoms): of = SystemGeometryObjectiveFunction.FromSystem(molecule) gradientDeviation = of.TestGradients(log=log) maximumGradientDeviation = max(maximumGradientDeviation, gradientDeviation) # . Error. except Exception as e: numberErrors += 1 if log is not None: log.Text("\nError occurred> " + e.args[0] + "\n") # . Get the observed and reference data. observed = {} referenceData = TestDataSet("MNDO UHF Energies") if self.testGradients: observed["Gradient Error"] = maximumGradientDeviation referenceData.AddDatum( TestReal( "Gradient Error", 0.0, referenceData, absoluteErrorTolerance=_GradientAbsoluteErrorTolerance, 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 isOK = isOK and (numberErrors == 0) self.assertTrue(isOK)
def GrowingStringInitialPath(system, npoints, point0, pointn, path, **keywordArguments): """Use a \"growing string\" method for generating an initial path.""" # . Get some options. log = keywordArguments.pop("log", logFile) sequence = keywordArguments.pop("sequence", "Forward").lower() # . Get the number of points. npoints = max(npoints, 2) # . Check for fixed atoms. QFIXED = (system.hardConstraints is not None) and ( system.hardConstraints.NumberOfFixedAtoms() > 0) # . Save the current system coordinates. temporary = Clone(system.coordinates3) # . Create the trajectory and write the first frame. trajectory = SystemGeometryTrajectory(path, system, mode="w") trajectory.WriteFrame(point0, frame=0) # . Get the first and last energies. energies = {} point0.CopyTo(system.coordinates3) energies[0] = system.Energy(log=log) pointn.CopyTo(system.coordinates3) if not QFIXED: system.coordinates3.Superimpose(point0) energies[npoints - 1] = system.Energy(log=log) # . Save the last point. trajectory.WriteFrame(system.coordinates3, frame=npoints - 1) # . Generate intermediate points. if npoints > 2: # . Set up the optimizer. algorithm = keywordArguments.pop("optimizer", LBFGSMinimizer) options = dict(_MinimizerOptions) options.update(keywordArguments) optimizer = algorithm(**options) optimizer.Summary(log=log) # . Set up the objective function. of = SystemGeometryObjectiveFunction.FromSystem(system) # . Get variables for the first and last points and the tangent constraint. first = Real1DArray.WithExtent(of.nvariables) last = Real1DArray.WithExtent(of.nvariables) tangent = Real1DArray.WithExtent(of.nvariables) # . Save the last point (given it is already in system.coordinates3). of.VariablesGet(last) # . Save the first point. point0.CopyTo(system.coordinates3) of.VariablesGet(first) # . Generate the sequence over which iterations are to occur. sequenceData = [] if sequence == "alternate": for i in range((npoints - 2) // 2): sequenceData.append( (first, last, i + 1, npoints - 2 - (2 * i))) sequenceData.append( (last, first, npoints - 2 - i, npoints - 2 - (2 * i + 1))) if (npoints - 2) % 2 != 0: sequenceData.append((first, last, (npoints - 2) // 2 + 1, 1)) elif sequence == "backward": for i in range(npoints - 2): sequenceData.append( (last, first, npoints - 2 - i, npoints - 2 - i)) elif sequence == "forward": for i in range(npoints - 2): sequenceData.append((first, last, i + 1, npoints - 2 - i)) else: raise ArgumentError("Unknown sequence option - " + sequence + ".") # . Loop over points. for (start, stop, index, remainder) in sequenceData: # . Get the new point to optimize and the tangent constraint. stop.CopyTo(tangent) tangent.AddScaledArray(-1.0, start) start.AddScaledArray(1.0 / float(remainder + 1), tangent) tangent.Normalize() # . Set up the object function. of.RemoveRotationTranslation(reference=point0) of.AddLinearConstraint(tangent) of.VariablesPut(start) # . Minimize and save the point. optimizer.Iterate(of, log=log) of.VariablesGet(start) energies[index] = system.Energy(log=log) trajectory.WriteFrame(system.coordinates3, frame=index) # . Finish up. system.coordinates3 = temporary trajectory.Close() # . Output. if LogFileActive(log): table = log.GetTable(columns=[30, 20]) table.Start() table.Title("Growing String Structure Energies") table.Heading("Structure") table.Heading("Energy") keys = energies.keys() keys.sort() for key in keys: table.Entry(repr(key)) table.Entry("{:.3f}".format(energies[key])) table.Stop()
def NormalModes_SystemGeometry(system, hessian=None, log=logFile, modify=None, title="Harmonic Frequencies (cm^(-1))"): """Determine the normal modes for a system.""" # . Get some options. if modify is None: modopt = None else: modopt = modify.upper() # . Get the Hessian with mass-weighting. of = SystemGeometryObjectiveFunction.FromSystem(system) of.DefineWeights() n = of.NumberOfVariables() if hessian is None: x = Real1DArray.WithExtent(n) x.Set(0.0) of.VariablesGet(x) hessian = of.NumericalHessian(x) # . Get the mass-weighted rotation-translation vectors and count their number. of.RemoveRotationTranslation() if of.linearScalars is None: nrtmodes = 0 else: nrtmodes = len(of.linearScalars) # . Modify the Hessian. if modopt in _MODIFYOPTIONS: if modopt == "PROJECT": hessian.ProjectOutVectors(of.linearVectors) elif modopt == "RAISE": hessian.Raise(of.linearVectors, _RAISEEIGENVALUE) # . Diagonalization. # . Maybe should save hessian here as it is destroyed by the diagonalization. eigenvalues = Real1DArray.WithExtent(n) eigenvalues.Set(0.0) eigenvectors = Real2DArray.WithExtents(n, n) eigenvectors.Set(0.0) hessian.Diagonalize(eigenvalues, eigenvectors) # . Convert eigenvalues to frequencies. for (i, e) in enumerate(eigenvalues): f = math.sqrt(math.fabs(e)) * _TO_WAVENUMBERS if e < 0.0: f *= -1.0 eigenvalues[i] = f # . Un-mass-weight the modes. for r in range(n): w = 1.0 / of.variableWeights[r] for c in range(n): eigenvectors[r, c] *= w # . Do some printing. if LogFileActive(log): table = log.GetTable(columns=_NFREQUENCYCOLUMNS * [_FREQUENCYWIDTHS]) table.Start() table.Title(title) for f in eigenvalues: table.Entry(_FREQUENCYFORMAT.format(f)) table.Stop() # . Save all data. state = NormalModeState(dimension=n, freeAtoms=of.freeAtoms, frequencies=eigenvalues, modes=eigenvectors, nrtmodes=nrtmodes, weights=of.variableWeights) system.configuration.SetTemporaryAttribute("nmState", state) # . Finish up. return state
def QuasiHarmonic_SystemGeometry(system, log=logFile, modify=None, temperature=300.0, title="Quasi-Harmonic Frequencies (cm^(-1))", trajectories=None): """Determine the quasi-harmonic modes for a system.""" # . Initialization. state = None # . Determine if any atoms are fixed. hc = system.hardConstraints if (hc is not None) and (hc.fixedAtoms is not None) and (len(hc.fixedAtoms) > 0): fixedAtoms = hc.fixedAtoms else: fixedAtoms = None # . Get the covariance matrix. covariance = CovarianceMatrix(trajectories, selection=fixedAtoms) # . Proceed with the analysis. if covariance is not None: # . Get some options. if modify is None: modopt = None else: modopt = modify.upper() # . Mass-weight the covariance matrix. # . Weights are square roots of masses. of = SystemGeometryObjectiveFunction.FromSystem(system) of.DefineWeights() n = of.NumberOfVariables() for i in range(n): wI = of.variableWeights[i] for j in range(i + 1): wJ = of.variableWeights[j] covariance[i, j] *= (wI * wJ) # . Get the mass-weighted rotation-translation vectors and count their number. of.RemoveRotationTranslation() if of.linearScalars is None: nrtmodes = 0 else: nrtmodes = len(of.linearScalars) # . Modify the Hessian. if modopt in _MODIFYOPTIONS: if modopt == "PROJECT": covariance.ProjectOutVectors(of.linearVectors) elif modopt == "RAISE": covariance.Raise(of.linearVectors, 0.0) # . Diagonalization. eigenValues = Real1DArray.WithExtent(n) eigenValues.Set(0.0) eigenVectors = Real2DArray.WithExtents(n, n) eigenVectors.Set(0.0) covariance.Diagonalize(eigenValues, eigenVectors) # . Convert eigenvalues to frequencies. conversionFactor = math.sqrt(_TO_KJMOL * temperature) * _TO_WAVENUMBERS numberZero = 0 for (i, e) in enumerate(eigenValues): eAbs = math.fabs(e) if eAbs <= _QHTolerance: f = 0.0 numberZero += 1 else: f = math.sqrt(1.0 / eAbs) * conversionFactor if e < 0.0: f *= -1.0 eigenValues[i] = f # . Un-mass-weight the modes. for r in range(n): w = 1.0 / of.variableWeights[r] for c in range(n): eigenVectors[r, c] *= w # . Reverse in place (excluding zero modes). temporary = Real1DArray.WithExtent(n) for i in range((n - numberZero) // 2): # . Indices. lower = i + numberZero upper = n - i - 1 # . Eigenvalues. e = eigenValues[upper] eigenValues[upper] = eigenValues[lower] eigenValues[lower] = e # . Eigenvectors. for j in range(n): temporary[j] = eigenVectors[j, upper] for j in range(n): eigenVectors[j, upper] = eigenVectors[j, lower] for j in range(n): eigenVectors[j, lower] = temporary[j] # . Do some printing. if LogFileActive(log): table = log.GetTable(columns=_NFREQUENCYCOLUMNS * [_FREQUENCYWIDTHS]) table.Start() table.Title(title) for f in eigenValues: table.Entry(_FREQUENCYFORMAT.format(f)) table.Stop() # . Save all data. state = NormalModeState(dimension=n, freeAtoms=of.freeAtoms, frequencies=eigenValues, modes=eigenVectors, nrtmodes=nrtmodes, weights=of.variableWeights) system.configuration.SetTemporaryAttribute("qhState", state) # . Finish up. return state
def runTest(self): """The test.""" # . Initialization. log = self.GetLog() numberErrors = 0 if self.testGradients: maximumGradientDeviation = 0.0 # . Loop over systems. for testSystem in self.ciTestSystems: # . Get the molecule. molecule = testSystem.GetSystem(log=log) # . Determine an energy. try: energy = molecule.Energy(log=log, doGradients=True) # . Charges. charges = molecule.AtomicCharges() charges.Print(log=log, title="Charges") if log is not None: log.Paragraph("Total Charge = {:.3f}".format(sum(charges))) charges = molecule.AtomicCharges(spinDensities=True) charges.Print(log=log, title="Spin Densities") if log is not None: log.Paragraph("Total Spin Density = {:.3f}".format( sum(charges))) # . Printing. if self.doPrinting: molecule.configuration.qcState.CIWavefunctionSummary( log=log) molecule.configuration.qcState.CIVectorsTable(log=log, nvectors=20) molecule.energyModel.qcModel.PrintOnePDMArrays( molecule.configuration, log=log) # . Gradient testing. if self.testGradients and (len(molecule.atoms) < self.maximumAtoms): of = SystemGeometryObjectiveFunction.FromSystem(molecule) gradientDeviation = of.TestGradients(delta=5.0e-05, log=log, tolerance=3.0e-04) maximumGradientDeviation = max(maximumGradientDeviation, gradientDeviation) # . Error. except Exception as e: numberErrors += 1 if log is not None: log.Text("\nError occurred> " + e.args[0] + "\n") # . Get the observed and reference data. observed = {} referenceData = TestDataSet("MNDO CI Energies") if self.testGradients: observed["Gradient Error"] = maximumGradientDeviation referenceData.AddDatum( TestReal( "Gradient Error", 0.0, referenceData, absoluteErrorTolerance=_GradientAbsoluteErrorTolerance, 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 isOK = isOK and (numberErrors == 0) self.assertTrue(isOK)