def _PlaceIonsAtGridPoints ( ions, grid, unoccupied ):
    """Place ions at grid points."""
#
# . Placement is currently done randomly. In principle it could also be done using energies using a procedure such as:
#
# - Calculate potentials (1/r,1/r^6,1/r^12) on unoccupied grid points due to protein.
# - Loop over ions (+/- alternate pairs):
#       Determine energy of each grid points as q * pot(1/r) + e * s^3 * pot(1/r^6) + ...
#       Find point with lowest energy and put ion at this point.
#       Update potentials due to the ion at this point.
#
# . Requires a single NB model method that calculates/updates potentials.
#
# . However, a similar result can be achieved by using random placement, doing a Monte Carlo (no waters) with
# . an NBModel with dielectric of 80 and then choosing low energy conformations.
#
    # . Number of ions.
    nions = len ( ions.atoms )

    # . Get a random number of points from the unoccupied sites.
    points = sample ( unoccupied, nions )

    # . Calculate the coordinates - these are implicitly sorted due to the selection.
    coordinates3 = Coordinates3_FromGrid ( grid, selection = Selection.FromIterable ( points ) )

    # . Shuffle again.
    points = sample ( range ( nions ), nions )
    for ( n, p ) in enumerate ( points ):
        for i in range ( 3 ): ions.coordinates3[n,i] = coordinates3[p,i]
def CovarianceMatrix(*arguments, **keywordArguments):
    """Calculate the covariance matrix for selected particles."""

    # . Initialization.
    covariance = None

    # . Get the trajectory and associated system data.
    (system, trajectories) = _GetSystemAndTrajectoriesFromArguments(*arguments)

    # . Get the selection and the size of the problem.
    selection = keywordArguments.pop("selection", None)
    if selection is None:
        selection = Selection.FromIterable(range(len(system.atoms)))
    n = 3 * len(selection)

    # . Get the average positions.
    averagePositions = keywordArguments.pop("averagePositions", None)
    if averagePositions is None:
        averagePositions = AveragePositions(trajectories, selection=selection)
    _CheckForUnknownOptions(keywordArguments)

    # . Continue processing.
    if (n > 0) and (averagePositions is not None):

        # . Allocate space.
        covariance = SymmetricMatrix.WithExtent(n)
        covariance.Set(0.0)
        displacement = Real1DArray.WithExtent(n)
        displacement.Set(0.0)

        # . Loop over trajectory frames.
        numberFrames = 0
        for trajectory in trajectories:
            trajectory.ReadHeader()
            while trajectory.RestoreOwnerData():
                frame = system.coordinates3
                for (p, i) in enumerate(selection):
                    displacement[3 * p] = frame[i, 0] - averagePositions[p, 0]
                    displacement[3 * p +
                                 1] = frame[i, 1] - averagePositions[p, 1]
                    displacement[3 * p +
                                 2] = frame[i, 2] - averagePositions[p, 2]
                for i in range(n):
                    dI = displacement[i]
                    for j in range(i + 1):
                        covariance[i, j] += (dI * displacement[j])
            trajectory.ReadFooter()
            trajectory.Close()
            numberFrames += len(trajectory)

        # . Scale.
        if numberFrames > 0: covariance.Scale(1.0 / float(numberFrames))

    return covariance
 def ToFixedAtoms(self, system):
     """Define fixed atoms for the system."""
     natoms = self.counters.get("Atoms", 0)
     if natoms > 0:
         # . Get the fixed atom indices.
         indices = []
         for (index, datum) in enumerate(self.atoms):
             flag = datum[8]
             if flag == 1: indices.append(index)
         # . Define the fixed atoms.
         if len(indices) > 0:
             system.DefineFixedAtoms(Selection.FromIterable(indices))
def BuildSolventBox ( crystalClass, symmetryParameters, molecule, density, log = logFile, randomNumberGenerator = None ):
    """Build a solvent box.

    No attempt is made to avoid overlapping molecules as it is assumed this will be corrected in a subsequent optimization process.
    """

    # . Initialization.
    solvent = None

    # . Find the number of solvent molecules that fit in the box.
    nmolecules = SolventMoleculeNumber ( molecule, symmetryParameters, density )

    # . Check the number of molecules.
    if nmolecules > 0:

        # . Create the solvent system.
        molecule.coordinates3.ToPrincipalAxes ( )
        solvent = MergeRepeatByAtom ( molecule, nmolecules )
        solvent.DefineSymmetry ( crystalClass = crystalClass, a     = symmetryParameters.a,     \
                                                              b     = symmetryParameters.b,     \
                                                              c     = symmetryParameters.c,     \
                                                              alpha = symmetryParameters.alpha, \
                                                              beta  = symmetryParameters.beta,  \
                                                              gamma = symmetryParameters.gamma  )

        # . Check the random number generator.
        if randomNumberGenerator is None: randomNumberGenerator = RandomNumberGenerator.WithRandomSeed ( )

        # . Do random rotations and translations.
        natoms      = len ( molecule.atoms )
        rotation    = Matrix33.Null ( )
        selection   = Selection.FromIterable ( range ( natoms ) )
        translation = Vector3.Null ( )
        for i in range ( nmolecules ):
            rotation.RandomRotation ( randomNumberGenerator )
            solvent.coordinates3.Rotate  ( rotation,    selection = selection )
            for j in range ( 3 ): translation[j] = randomNumberGenerator.NextReal ( )
            symmetryParameters.M.ApplyTo ( translation )
            solvent.coordinates3.Translate ( translation, selection = selection )
            selection.Increment ( natoms )

        # . Do some printing.
        if LogFileActive ( log ):
            summary = log.GetSummary ( )
            summary.Start ( "Cubic Solvent Box Summary" )
            summary.Entry ( "Number of Molecules", "{:d}"  .format ( nmolecules                        ) )
            summary.Entry ( "Density (kg m^-3)",   "{:.3f}".format ( SystemDensity ( solvent )         ) )
            summary.Entry ( "Box Volume",          "{:.3f}".format ( solvent.symmetryParameters.volume ) )
            summary.Stop ( )

    # . Return the system.
    return solvent
Example #5
0
 def TypeAtoms(self, connectivity, sequence, log):
     """Assign atom types and charges to the atoms."""
     # . Initialization.
     atomCharges = [0.0 for i in range(len(connectivity.atoms))]
     atomTypes = [None for i in range(len(connectivity.atoms))]
     untypedAtoms = Selection.FromIterable(range(len(atomTypes)))
     # . Type the atoms.
     self.TypeBySequence(sequence, atomTypes, atomCharges, untypedAtoms)
     self.TypeByPattern(connectivity, atomTypes, atomCharges, untypedAtoms)
     # . Check for untyped atoms.
     self.CheckUntypedAtoms(connectivity, untypedAtoms, log)
     # . Finish up.
     return (atomTypes, atomCharges)
Example #6
0
 def FilterAtoms ( self, filterlevel ):
     """Filter out Mopac-specific atoms."""
     if self.QPARSED and ( filterlevel > -3 ):
         atomicNumbers = []
         selected      = []
         for ( i, a ) in enumerate ( self.atomicNumbers ):
             if a >= filterlevel:
                 atomicNumbers.append ( a )
                 selected.append      ( i )
         if len ( atomicNumbers ) < len ( self.atomicNumbers ):
             coordinates3 = Coordinates3.WithExtent ( len ( atomicNumbers ) )
             coordinates3.Gather ( self.coordinates3, Selection.FromIterable ( selected ) )
             self.atomicNumbers = atomicNumbers
             self.coordinates3  = coordinates3
def AveragePositions(*arguments, **keywordArguments):
    """Calculate the average positions for selected particles."""

    # . Initialization.
    positions = None

    # . Process arguments.
    (system, trajectories) = _GetSystemAndTrajectoriesFromArguments(*arguments)

    # . Get the selection (or all particles otherwise).
    selection = keywordArguments.pop("selection", None)
    if selection is None:
        selection = Selection.FromIterable(range(len(system.atoms)))
    _CheckForUnknownOptions(keywordArguments)

    # . Get the size of the problem.
    n = len(selection)
    if n > 0:

        # . Allocate space.
        positions = Coordinates3.WithExtent(n)
        positions.Set(0.0)

        # . Loop over trajectory frames.
        numberFrames = 0
        for trajectory in trajectories:
            trajectory.ReadHeader()
            while trajectory.RestoreOwnerData():
                frame = system.coordinates3
                for (p, i) in enumerate(selection):
                    positions[p, 0] += frame[i, 0]
                    positions[p, 1] += frame[i, 1]
                    positions[p, 2] += frame[i, 2]
            trajectory.ReadFooter()
            trajectory.Close()
            numberFrames += len(trajectory)

        # . Scale.
        if numberFrames > 0: positions.Scale(1.0 / float(numberFrames))

    return positions
Example #8
0
 def DefineQCModel(self, qcModel, log=logFile, qcSelection=None):
     """Define a quantum chemical model for the system."""
     if isinstance(qcModel, QCModel):
         # . Get an energy model in the correct state.
         if self.energyModel is None:
             self.__dict__["_energyModel"] = EnergyModel()
         else:
             self.energyModel.ClearQCModel(self.configuration,
                                           fixedAtoms=None)
         em = self.energyModel
         # . Assign a default electronic state if necessary.
         if self.electronicState is None:
             self.electronicState = ElectronicState()
         # . Get the QC atom selection and the boundary atoms.
         if (qcSelection is None) or (qcSelection.size == len(self.atoms)):
             atomindices = Selection.FromIterable(range(len(self.atoms)))
             boundaryatoms = {}
         else:
             atomindices = qcSelection
             boundaryatoms = em.IdentifyBoundaryAtoms(atomindices)
         # . Set up the QC atom data.
         qcAtoms = QCAtomContainer_FromAtomContainer(
             self.atoms, atomindices, boundaryatoms,
             getattr(qcModel, "linkAtomRatio", True))
         # . Get the qcParameters.
         anlist = qcAtoms.UniqueAtomicNumbers()
         qcParameters = qcModel.DefineParameters(anlist, log=log)
         # . Fill in the remaining qcatom data.
         qcAtoms.AssignParameterData(anlist, qcParameters)
         # . Save the data.
         em.qcAtoms = qcAtoms
         em.qcModel = qcModel
         em.__dict__["qcParameters"] = qcParameters
         em.MakeLabel()
         # . Modify the MM terms if appropriate.
         em.DeactivateQCAtomMMTerms()
         # . Deactivate MM terms if fixed atoms are defined.
         if (self.hardConstraints is not None):
             em.DeactivateFixedAtomMMTerms(self.hardConstraints.fixedAtoms)
         # . Check the total MM charge.
         em.CheckActiveMMAtomTotalCharge()
                "P61"     : [ "(x,y,z)", "(-y,x-y,z+1/3)", "(-x+y,-x,z+2/3)", "(-x,-y,z+1/2)", "(y,-x+y,z+5/6)", "(x-y,x,z+1/6)" ],
                "P21c"    : [ "(x,y,z)", "(-x,y+1/2,-z+1/2)", "(-x,-y,-z)", "(x,-y+1/2,z+1/2)" ],
                "P21a"    : [ "(x,y,z)", "(-x+1/2,y+1/2,-z)", "(-x,-y,-z)", "(x+1/2,-y+1/2,z)" ],
                "R3"      : [ "(x,y,z)", "(z,x,y)", "(y,z,x)" ] }

# . Convert to transformation sets.
_transformationSets = {}
for ( key, olist ) in _operations.iteritems ( ):
    tset = []
    for o in olist:
        tset.append ( Transformation3_FromSymmetryOperationString ( o ) )
    _transformationSets[key] = Transformation3Container.WithTransformations ( tset )

# . Molecule definitions.
_keywordLabels = ( "label", "canQCOptimize", "qcSelection", "qcCharge", "vacuumEnergy", "crystalEnergy", "crystalClass", "transformations", "crystalParameters" )
_moleculeData  = ( ( "ALAALA",   False, Selection.FromIterable ( range (  6, 10 ) ),  0,  -178.7095,  -677.7298, CrystalClassTetragonal   ( ), _transformationSets["I4"],      { "a" : 17.9850, "c" : 5.1540 } ),
                   ( "ALAMET01", False, Selection.FromIterable ( range ( 16, 27 ) ),  0,  -135.0084,  -652.9681, CrystalClassMonoclinic   ( ), _transformationSets["P21c"],    { "a" : 13.089, "b" : 5.329, "c" : 15.921, "beta" :  108.57 } ),
                   ( "AQARUF",   False, Selection.FromIterable ( range (  6, 19 ) ),  0,  -144.5558,  -608.3551, CrystalClassHexagonal    ( ), _transformationSets["P61"],     { "a" : 14.3720, "c" : 9.8282 } ),
                   ( "BEVXEF01", False, Selection.FromIterable ( range ( 23, 29 ) ),  0,  -240.0604,  -878.7555, CrystalClassOrthorhombic ( ), _transformationSets["P212121"], { "a" : 9.6590, "b" : 9.6720, "c" : 10.7390 } ),
                   ( "GLYALB",   False, Selection.FromIterable ( range ( 13, 17 ) ),  0,   -44.8402,  -562.9905, CrystalClassOrthorhombic ( ), _transformationSets["P212121"], { "a" : 9.6930, "b" : 9.5240, "c" : 7.5370 } ),
                   ( "GLYGLY",   False, Selection.FromIterable ( range ( 14, 17 ) ), -1,  -184.8863,  -687.4449, CrystalClassMonoclinic   ( ), _transformationSets["P21a"],    { "a" : 7.812, "b" : 9.566, "c" : 9.410, "beta" :  124.60 } ),
                   ( "GUFQON",   False, Selection.FromIterable ( range ( 13, 18 ) ),  0,  -191.1490,  -511.8117, CrystalClassOrthorhombic ( ), _transformationSets["P212121"], { "a" : 7.2750, "b" : 9.0970, "c" : 10.5070 } ),
                   ( "HXACAN19", True,  Selection.FromIterable ( range ( 16, 20 ) ),  0,   157.7170,    24.6588, CrystalClassMonoclinic   ( ), _transformationSets["P21a"],    { "a" : 12.8720, "b" : 9.3700, "c" : 7.0850, "beta" :  115.6200 } ),
                   ( "IWANID",   False, Selection.FromIterable ( range ( 37, 51 ) ),  0,  4380.9282,  4070.8472, CrystalClassMonoclinic   ( ), _transformationSets["C2"],      { "a" : 23.091, "b" : 5.494, "c" : 17.510, "beta" :  117.88 } ),
                   ( "LCDMPP10", True,  Selection.FromIterable ( range (  4,  8 ) ),  0,   157.3277,    40.3629, CrystalClassTriclinic    ( ), _transformationSets["P1"],      { "a" : 8.067, "b" : 6.082, "c" : 5.155, "alpha" : 131.7, "beta" :  82.4, "gamma" : 106.6 } ),
                   ( "WIRYEB",   False, Selection.FromIterable ( range (  6, 16 ) ),  0,  -155.7355,  -612.6186, CrystalClassHexagonal    ( ), _transformationSets["P61"],     { "a" : 14.4240, "c" : 9.9960 } ),
                   ( "WABZOO",   True,  Selection.FromIterable ( range ( 0, 4 ) + range ( 10, 14 ) + range ( 18, 25 ) ), 0, 209.9697,   152.9967, CrystalClassRhombohedral ( ), _transformationSets["R3"], { "a" : 12.5940 , "alpha" : 118.0300 } ) )

# . Options for expanding to P1 symmetry.
_defaultRange = range ( 1 ) #range ( -1, 2 )
_aRange       = _defaultRange
    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)
def SolvateSystemBySuperposition ( solute, solvent, log = logFile, excludeHydrogens = True, reorientSolute = True, printPairs = False, scaleradii = 0.75 ):
    """Solvate a system by superposition."""

    # . Check that the solvent has a full connectivity.
    if not solvent.connectivity.HasFullConnectivity ( ): raise ValueError ( "The solvent must have a full connectivity." )

    # . Create a sequence.
    if solute.sequence is not None:
        entityLabel = DetermineUniqueEntityLabel ( solute, label = "W" )
        CreateHomogeneousIsolateSequence ( solvent, entityLabel = entityLabel )

    # . Merge the two systems.
    solution = MergeByAtom ( solute, solvent )

    # . Get the atom masses and selections corresponding to the solute and solvent atoms.
    masses       = solution.atoms.GetItemAttributes ( "mass" )
    nsolute      = len ( solute.atoms  )
    nsolvent     = len ( solvent.atoms )
    soluteatoms  = Selection.FromIterable ( range ( nsolute                     ) )
    solventatoms = Selection.FromIterable ( range ( nsolute, nsolute + nsolvent ) )

    # . Reorient the solute coordinates if required.
    if reorientSolute: solution.coordinates3.ToPrincipalAxes ( selection = soluteatoms, weights = masses )

    # . Check the extents of the solute and solvent - to ensure the box is big enough!
    ( origin1, extents1 ) = solution.coordinates3.EnclosingOrthorhombicBox ( selection = soluteatoms  )
    ( origin2, extents2 ) = solution.coordinates3.EnclosingOrthorhombicBox ( selection = solventatoms )
    extents2.AddScaledVector3 ( -1.0, extents1 )
    if min ( extents2 ) < 0.0: raise ValueError ( "It is likely that the solvent box is too small for the solute." )

    # . Move the center of the solute atoms to that of the solvent atoms.
    translation = Clone ( origin2 )
    translation.AddScaledVector3 (  0.5, extents2 )
#    translation.AddScaledVector3 ( -0.5, extents1 ) # . Not needed as done above.
    translation.AddScaledVector3 ( -1.0, origin1  )
    solution.coordinates3.Translate ( translation, selection = soluteatoms )

    # . Reduce the selections if hydrogens are to be excluded.
    if excludeHydrogens:
        indices = []
        for i in soluteatoms:
            if solution.atoms[i].atomicNumber != 1: indices.append ( i )
        soluteatoms = Selection.FromIterable ( indices )
        indices = []
        for i in solventatoms:
            if solution.atoms[i].atomicNumber != 1: indices.append ( i )
        solventatoms = Selection.FromIterable ( indices )

    # . Get the radii.
    radii = solution.atoms.GetItemAttributes ( "vdwRadius" )
    radii.Scale ( scaleradii )

    # . Get the pairlist.
    pairlist = CrossPairList_FromSingleCoordinates3 ( solution.coordinates3, selection1 = solventatoms, selection2 = soluteatoms, radii = radii )
    npairs   = len ( pairlist )

    # . Find the solvent atoms in the pairlist (which are the first indices in the list).
    indices = set ( )
    for ( i, j ) in pairlist: indices.add ( i )

    # . Now find the indices of all the atoms in the corresponding solvent isolates.
    if len ( indices ) > 0:
        toremove  = solution.connectivity.isolates.GetAllIndices ( Selection.FromIterable ( indices ) )
        ntoremove = len ( toremove )
        # . Remove unwanted atoms.
        reduced = PruneByAtom ( solution, toremove.Complement ( upperBound = nsolute + nsolvent ) )
        if solution.sequence is not None: RenumberEntityComponents ( reduced, entityLabels = [ entityLabel ] )
    else:
        ntoremove = 0
        reduced   = solution

    # . Set the symmetry of solution by copying that of solvent.
    if ( solvent.symmetry is not None ) and ( solvent.symmetryParameters is not None ):
        keywordArguments = solvent.symmetryParameters.__getstate__ ( )
        keywordArguments["crystalClass"]    = solvent.symmetry.crystalClass
        keywordArguments["transformations"] = solvent.symmetry.transformations
        reduced.DefineSymmetry ( **keywordArguments )

    # . Do some printing.
    if LogFileActive ( log ):

        # . Distances.
        if printPairs:
            table   = log.GetTable ( columns = [ 10, 10, 20, 20 ] )
            table.Start ( )
            table.Title ( "Solute/Solvent Pairs" )
            table.Heading ( "Solvent"  )
            table.Heading ( "Solute"   )
            table.Heading ( "Distance" )
            table.Heading ( "Cutoff"   )
            for ( i, j ) in pairlist:
                table.Entry ( PeriodicTable.Symbol ( solution.atoms[i].atomicNumber, index = i ) )
                table.Entry ( PeriodicTable.Symbol ( solution.atoms[j].atomicNumber, index = j ) )
                table.Entry ( "{:.3f}".format ( solution.coordinates3.Distance ( i, j ) ) )
                table.Entry ( "{:.3f}".format ( radii[i] + radii[j]                     ) )
            table.Stop ( )

        # . Summary.
        summary = log.GetSummary ( )
        summary.Start ( "Solvation By Superposition Summary" )
        summary.Entry ( "Solute Atoms"         , "{:d}".format ( nsolute              ) )
        summary.Entry ( "Solvent Atoms"        , "{:d}".format ( nsolvent - ntoremove ) )
        summary.Entry ( "Atoms Removed"        , "{:d}".format ( ntoremove            ) )
        summary.Entry ( "Solute/Solvent Pairs" , "{:d}".format ( npairs               ) )
        summary.Stop ( )

    # . Finish up.
    return reduced
Example #12
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 RadialDistributionFunction(*arguments, **keywordArguments):
    """Calculate a radial distribution function."""

    # . Get the trajectory and associated system data.
    (system, trajectories) = _GetSystemAndTrajectoriesFromArguments(*arguments)

    # . Keyword arguments.
    bins = keywordArguments.pop("bins", 100)
    log = keywordArguments.pop("log", logFile)
    safety = keywordArguments.pop("safety", _DEFAULTSAFETY)
    selection1 = keywordArguments.pop("selection1", None)
    selection2 = keywordArguments.pop("selection2", None)
    upper = keywordArguments.pop("maximumR", None)
    if selection1 is None:
        selection1 = Selection.FromIterable(range(len(system.atoms)))
    if selection2 is None: selection2 = selection1
    _CheckForUnknownOptions(keywordArguments)

    # . Get the numbers of particles.
    np1 = len(selection1)
    np2 = len(selection2)

    # . Check for a cubic system.
    try:
        cc = system.symmetry.crystalClass
        if not isinstance(cc, CrystalClassCubic): raise
    except:
        raise ValueError("System does not have cubic symmetry.")

    # . Estimate an upper bound.
    if upper is None:
        try:
            upper = (system.symmetryParameters.a - safety) / 2.0
        except:
            raise ValueError(
                "Please supply an upper bound for the RDF calculation.")

    # . Initialization.
    lower = 0.0
    distances = []
    histogram = [0 for i in range(bins)]
    rdf = []

    # . Calculate the width of each bin.
    width = (upper - lower) / float(bins)
    vacc = 0.0

    # . Loop over trajectory frames.
    numberFrames = 0
    for trajectory in trajectories:
        trajectory.ReadHeader()
        while trajectory.RestoreOwnerData():

            # . Get the frame.
            frame = system.coordinates3
            numberFrames += 1

            # . Accumulate the volume.
            a = system.symmetryParameters.a
            vacc += a**3

            # . Check a.
            if upper > 0.5 * a:
                raise ValueError(
                    "Box does not satisfy minimum image convention.")

            # . Bin the distances.
            # . This loop involves duplicate work for self rdfs.
            for i in selection1:
                for j in selection2:
                    if i != j:
                        dr = frame.Displacement(i, j)
                        for c in range(3):
                            x = a * round(dr[c] / a)
                            dr[c] -= x
                        r = dr.Norm2()
                        if (r >= lower) and (r < upper):
                            b = int((r - lower) / width)
                            histogram[b] += 1

        # . Finish up.
        trajectory.ReadFooter()
        trajectory.Close()

    # . Calculate g(r).
    fact = 4.0 * math.pi * float(np1 * np2 * numberFrames**2) / (3.0 * vacc)
    for i in range(bins):
        rlower = lower + float(i) * width
        rupper = rlower + width
        distances.append(rlower + 0.5 * width)
        rdf.append(float(histogram[i]) / (fact * (rupper**3 - rlower**3)))

    # . Output the results.
    if LogFileActive(log):
        table = log.GetTable(columns=[20, 20])
        table.Start()
        table.Title("Radial Distribution Function")
        table.Heading("Distance")
        table.Heading("g(r)")
        for (r, g) in zip(distances, rdf):
            table.Entry("{:20.4f}".format(r))
            table.Entry("{:20.4f}".format(g))
        table.Stop()

    # . Return results.
    return (distances, rdf)
Example #14
0
solution.DefineNBModel  ( nbModel )
solution.Summary ( )

# . Refinement.
if _Refine:

    # . Check energies.
    solute.Energy ( )
    for system in ( solvent, solution ):
        system.DefineNBModel ( nbModel )
        system.Energy ( )

    # . Get selections for the protein atoms in the A and I chains.
    protein   = AtomSelection.FromAtomPattern ( solution, "A:*:*" ) | AtomSelection.FromAtomPattern ( solution, "I:*:*" )
    hydrogens = AtomSelection.FromAtomAttributes ( solution, "atomicNumber", 1 )
    heavies   = Selection.FromIterable ( protein - hydrogens )
    protein   = Selection.FromIterable ( protein )

    # . Fix all protein atoms.
    solution.DefineFixedAtoms ( protein )
    solution.Summary ( )

    # . Optimization.
    if _Optimize:
        ConjugateGradientMinimize_SystemGeometry ( solution                    ,
                                                   maximumIterations    =  200 ,
                                                   logFrequency         =   10 ,
                                                   rmsGradientTolerance = 10.0 )

    # . Define a normal deviate generator in a given state.
    normalDeviateGenerator = NormalDeviateGenerator.WithRandomNumberGenerator ( RandomNumberGenerator.WithSeed ( 517152 ) )
import math, os.path

from pBabel import MOLFile_ToSystem
from pCore import logFile, LogFileActive, Selection
from pMolecule import ElectronicState, MMModelOPLS, NBModelFull

#===================================================================================================================================
# . Parameters for system definitions.
#===================================================================================================================================
# . Paths.
_dataPath = os.path.join(os.getenv("PDYNAMO_PMOLECULE"), "data", "mol")

# . Molecule definitions.
_keywordLabels = ("label", "dataPath", "fileName", "qcCharge", "multiplicity",
                  "qcSelection")
_moleculeData  = ( ( "Alanine Dipeptide"   , _dataPath, "bAla_c7eq"        , 0, 1, Selection.FromIterable ( range ( 10, 14 ) ) ), \
                   ( "Cyclohexane 6"       , _dataPath, "cyclohexane"      , 0, 1, Selection.FromIterable ( range (  6     ) ) ), \
                   ( "Cyclohexane 9"       , _dataPath, "cyclohexane"      , 0, 1, Selection.FromIterable ( range (  9     ) ) ), \
                   ( "Tyrosine Dipeptide 1", _dataPath, "tyrosineDipeptide", 0, 1, Selection.FromIterable ( range (  6, 14 ) + range ( 22, 29 ) ) ), \
                   ( "Tyrosine Dipeptide 2", _dataPath, "tyrosineDipeptide", 1, 2, Selection.FromIterable ( range (  6, 14 ) + range ( 22, 29 ) ) ), \
                   ( "Water Dimer 1"       , _dataPath, "waterDimer_cs"    , 0, 1, Selection.FromIterable ( range (  3     ) ) ), \
                   ( "Water Dimer 2"       , _dataPath, "waterDimer_cs"    , 0, 1, Selection.FromIterable ( range (  3,  6 ) ) )  )


#===================================================================================================================================
# . Class for a QC/MM test system.
#===================================================================================================================================
class QCMMTestSystem(object):
    """QC/MM test system."""
    def __init__(self, **kwargs):
        """Constructor."""
#===================================================================================================================================
# . Parameters for system definitions.
#===================================================================================================================================
# . Model definitions.
_converger = DIISSCFConverger(densityTolerance=1.0e-8, maximumSCFCycles=250)
_qcModelDFT = QCModelDFT(converger=_converger,
                         densityBasis="demon",
                         orbitalBasis="321g")
_qcModelMNDO = QCModelMNDO(converger=_converger)
_qcModelORCA = QCModelORCA("HF:6-31G*", "SCFCONV10", "EXTREMESCF")
_nbModel = NBModelABFS()

# . Job data.
# . Options: doQCMM for bottom layer, QC model for upper layer and QC selection for upper layer.
_jobData = { "Water Dimer 1"     : ( ( False, _qcModelDFT,  Selection.FromIterable ( range (  3     ) ) ), \
                                     ( False, _qcModelORCA, Selection.FromIterable ( range (  3,  6 ) ) ), \
                                     ( True,  _qcModelDFT,  Selection.FromIterable ( range (  3     ) ) )  ), \
             "Water Dimer 2"     : ( ( True,  _qcModelORCA, Selection.FromIterable ( range (  3,  6 ) ) ), ), \
             "Cyclohexane 9"     : ( ( False, _qcModelDFT,  Selection.FromIterable ( range (  6     ) ) ), \
                                     ( True,  _qcModelORCA, Selection.FromIterable ( range (  3,  6 ) ) )  ), \
             "Alanine Dipeptide" : ( ( False, _qcModelDFT,  Selection.FromIterable ( range ( 10, 14 ) ) ), \
                                     ( False, _qcModelORCA, Selection.FromIterable ( range ( 10, 14 ) ) ), \
                                     ( True,  _qcModelDFT,  Selection.FromIterable ( range ( 10, 14 ) ) ), \
                                     ( True,  _qcModelORCA, Selection.FromIterable ( range ( 10, 14 ) ) )  ) }

#===================================================================================================================================
# . Parameters for test.
#===================================================================================================================================
# . Tolerances.
_EnergyTolerance = 0.1
Example #17
0
#   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)
def SelfDiffusionFunction(*arguments, **keywordArguments):
    """Calculate the self diffusion function."""

    # . Get the trajectory and associated system data.
    (system, trajectories) = _GetSystemAndTrajectoriesFromArguments(*arguments)

    # . Keyword arguments.
    log = keywordArguments.pop("log", logFile)
    maximumTime = keywordArguments.pop("maximumTime", None)
    selection = keywordArguments.pop("selection", None)
    timeStep = keywordArguments.pop("timeStep", 1.0)
    if selection is None:
        selection = Selection.FromIterable(range(len(system.atoms)))
    _CheckForUnknownOptions(keywordArguments)

    # . Initialization.
    np = len(selection)  # . The number of particles.
    dSelf = []
    frames = []
    times = []

    # . Loop over trajectory frames.
    for trajectory in trajectories:
        trajectory.ReadHeader()
        while trajectory.RestoreOwnerData():
            frames.append(system.coordinates3.Prune(selection))
        trajectory.ReadFooter()
        trajectory.Close()

    # . Get the number of frames and tStop.
    numberFrames = len(frames)
    if maximumTime is None:
        tStop = numberFrames - 1
    else:
        tStop = int(maximumTime / timeStep)
        tStop = min(numberFrames - 1, tStop)

    # . Calculate the function - slow version.
    # . Loop over time differences to calculate.
    for t in range(tStop + 1):

        # . Initialization.
        tmax = numberFrames - t
        total = 0.0

        # . Loop over allowed increments.
        for t0 in range(tmax):
            # . Calculate differences.
            fa = frames[t0 + t]
            fb = frames[t0]
            for i in range(np):
                total += (fa[i, 0] - fb[i, 0])**2 + (
                    fa[i, 1] - fb[i, 1])**2 + (fa[i, 2] - fb[i, 2])**2

        # . Calculate dSelf.
        dSelf.append(total / float(3 * np * tmax))
        times.append(float(t) * timeStep)

    # . Output the results.
    if LogFileActive(log):
        table = log.GetTable(columns=[20, 20])
        table.Start()
        table.Title("Self-Diffusion Function")
        table.Heading("Time")
        table.Heading("Dself")
        for (t, d) in zip(times, dSelf):
            table.Entry("{:20.4f}".format(t))
            table.Entry("{:20.4f}".format(d))
        table.Stop()

    # . Return results.
    return (times, dSelf)
def BuildCubicSolventBox ( molecule, nmolecules, log = logFile, moleculesize = None, excludeHydrogens = True, QRANDOMROTATION = True, randomNumberGenerator = None, scalesafety = 1.1 ):
    """Build a cubic solvent box."""

    # . Get the number of molecules in each direction.
    nlinear = int ( math.ceil ( math.pow ( float ( nmolecules ), 1.0 / 3.0 ) ) )

    # . Get the indices of the occupied sites.
    sites = sample ( range ( nlinear**3 ), nmolecules )
    sites.sort ( )

    # . Get the number of atoms in the molecule and an appropriate selection.
    natoms    = len ( molecule.atoms )
    selection = Selection.FromIterable ( range ( natoms ) )

    # . Get a copy of molecule's coordinates (reorientated).
    coordinates3 = Clone ( molecule.coordinates3 )
    coordinates3.ToPrincipalAxes ( )

    # . Get the molecule size depending upon the input options.
    # . A molecule size has been specified.
    if moleculesize is not None:
        size = moleculesize
    # . Determine the size of the molecule as the diagonal distance across its enclosing orthorhombic box.
    else:
        radii = molecule.atoms.GetItemAttributes ( "vdwRadius" )
        if excludeHydrogens:
            atomicNumbers = molecule.atoms.GetItemAttributes ( "atomicNumber" )
            for ( i, atomicNumber ) in enumerate ( molecule.atoms.GetItemAttributes ( "atomicNumber" ) ):
                if atomicNumber == 1: radii[i] = 0.0
        ( origin, extents ) = coordinates3.EnclosingOrthorhombicBox ( radii = radii )
        size                = extents.Norm2 ( ) * scalesafety

    # . Create the new system - temporarily resetting the coordinates.
    temporary3            = molecule.coordinates3
    molecule.coordinates3 = coordinates3
    solvent               = MergeByAtom ( nmolecules * [ molecule ] )
    molecule.coordinates3 = temporary3

    # . Set the system symmetry.
    solvent.DefineSymmetry ( crystalClass = CrystalClassCubic ( ), a = size * float ( nlinear ) )

    # . Set up for random rotations.
    if QRANDOMROTATION:
        if randomNumberGenerator is None: randomNumberGenerator = RandomNumberGenerator.WithRandomSeed ( )
        rotation = Matrix33.Null ( )

    # . Loop over the box sites.
    origin      = 0.5 * float ( 1 - nlinear ) * size
    n           = 0
    translation = Vector3.Null ( )
    for i in range ( nlinear ):
        translation[0] = origin + size * float ( i )
        for j in range ( nlinear ):
            translation[1] = origin + size * float ( j )
            for k in range ( nlinear ):
                if len ( sites ) == 0: break
                translation[2] = origin + size * float ( k )
                # . Check for an occupied site.
                if sites[0] == n:
                    sites.pop ( 0 )
                    # . Randomly rotate the coordinates.
                    if QRANDOMROTATION:
                        rotation.RandomRotation ( randomNumberGenerator )
                        solvent.coordinates3.Rotate ( rotation, selection = selection )
                    # . Translate the coordinates.
                    solvent.coordinates3.Translate ( translation, selection = selection )
                    # . Increment the selection for the next molecule.
                    selection.Increment ( natoms )
                n += 1

    # . Do some printing.
    if LogFileActive ( log ):
        summary = log.GetSummary ( )
        summary.Start ( "Cubic Solvent Box Summary" )
        summary.Entry ( "Number of Molecules", "{:d}"  .format ( nmolecules                   ) )
        summary.Entry ( "Density (kg m^-3)",   "{:.3f}".format ( SystemDensity ( solvent )    ) )
        summary.Entry ( "Box Side",            "{:.3f}".format ( solvent.symmetryParameters.a ) )
        summary.Entry ( "Molecule Size",       "{:.3f}".format ( size                         ) )
        summary.Stop ( )

    # . Return the cubic system.
    return solvent
def CoordinateFluctuations(*arguments, **keywordArguments):
    """Calculate the coordinate fluctuations for selected particles."""

    # . Initialization.
    fluctuations = None

    # . Get the trajectory and associated system data.
    (system, trajectories) = _GetSystemAndTrajectoriesFromArguments(*arguments)

    # . Get the selection and the size of the problem.
    selection = keywordArguments.pop("selection", None)
    if selection is None:
        selection = Selection.FromIterable(range(len(system.atoms)))
    n = len(selection)

    # . Get the average positions.
    averagePositions = keywordArguments.pop("averagePositions", None)
    if averagePositions is None:
        averagePositions = AveragePositions(trajectories, selection=selection)

    # . Various other options.
    anisotropic = keywordArguments.pop("anisotropic", False)
    asBFactors = keywordArguments.pop("asBFactors", False)
    _CheckForUnknownOptions(keywordArguments)

    # . Continue processing.
    if (n > 0) and (averagePositions is not None):

        # . Allocate space.
        displacement = Coordinates3.WithExtent(n)
        if anisotropic: fluctuations = Real2DArray.WithExtents(n, 6)
        else: fluctuations = Real1DArray.WithExtent(n)
        displacement.Set(0.0)
        fluctuations.Set(0.0)

        # . Loop over trajectory frames.
        numberFrames = 0
        for trajectory in trajectories:
            trajectory.ReadHeader()
            while trajectory.RestoreOwnerData():
                frame = system.coordinates3
                if anisotropic:
                    for (p, i) in enumerate(selection):
                        dx = frame[i, 0] - averagePositions[p, 0]
                        dy = frame[i, 1] - averagePositions[p, 1]
                        dz = frame[i, 2] - averagePositions[p, 2]
                        fluctuations[p, 0] += dx * dx
                        fluctuations[p, 1] += dy * dx
                        fluctuations[p, 2] += dy * dy
                        fluctuations[p, 3] += dz * dx
                        fluctuations[p, 4] += dz * dy
                        fluctuations[p, 5] += dz * dz
                else:
                    for (p, i) in enumerate(selection):
                        fluctuations[p] += ( ( frame[i,0] - averagePositions[p,0] )**2 + \
                                             ( frame[i,1] - averagePositions[p,1] )**2 + \
                                             ( frame[i,2] - averagePositions[p,2] )**2 )
            trajectory.ReadFooter()
            trajectory.Close()
            numberFrames += len(trajectory)

        # . Scale.
        if numberFrames > 0: fluctuations.Scale(1.0 / float(numberFrames))

        # . Convert to B-factors if necessary.
        if asBFactors:
            conversionFactor = 8.0 * math.pi**2
            if not anisotropic: conversionFactor /= 3.0
            fluctuations.Scale(conversionFactor)

    # . Finish up.
    return fluctuations
 def Within ( self, distance, excludeSelf = False ):
     """Selection of atoms within a given distance."""
     # . Find all atoms within distance of the current selection.
     selfSelection = self.selection
     system        = self.system
     pairlist      = CrossPairList_FromSingleCoordinates3 ( system.coordinates3, selection1 = Selection.FromIterable ( selfSelection ), safety = distance )
     selection     = set ( selfSelection )
     for ( i, j ) in pairlist: selection.add ( j )
     # . Exclude self?
     if excludeSelf: selection -= self.selection
     # . Finish up.
     return self.__class__ ( selection = selection, system = self.system )