def AddLinearConstraint ( self, constraint ):
     """Add a linear constraint."""
     if len ( constraint ) != self.nvariables: raise ValueError ( "Invalid linear constraint length." )
     # . Orthogonalize to existing constraints.
     if self.linearVectors is not None:
         constraint = Clone ( constraint )
         self.linearVectors.ProjectOutOfArray ( constraint )
     # . Check to see if the constraint is valid.
     cnorm2 = constraint.Norm2 ( )
     if cnorm2 > 1.0e-10:
         constraint.Scale ( 1.0 / cnorm2 )
         # . Allocate space for new constraints.
         ncolumns = 1
         if self.linearVectors is not None: ncolumns += self.linearVectors.columns
         newconstraints = Real2DArray.WithExtents ( len ( constraint ), ncolumns )
         # . Copy over constraints.
         if self.linearVectors is not None:
             for r in range ( self.linearVectors.rows ):
                 for c in range ( self.linearVectors.columns ):
                     newconstraints[r,c] = self.linearVectors[r,c]
         for r in range ( len ( constraint ) ): newconstraints[r,ncolumns-1] = constraint[r]
         self.linearVectors = newconstraints
         # . Determine the linear scalars.
         self.linearScalars = Real1DArray.WithExtent ( self.linearVectors.columns )
         reference          = Real1DArray.WithExtent ( self.linearVectors.rows    )
         if self.rtReference is None: self.system.coordinates3.CopyToArray ( reference )
         else:                        self.rtReference.CopyToArray ( reference )
         self.linearVectors.VectorMultiply ( reference, self.linearScalars, 1.0, 0.0, transpose = True )
         # . Reset the number of degrees of freedom.
         self.degreesOfFreedom = self.nvariables - len ( self.linearScalars )
 def Initialize ( self ):
     """Initialization."""
     ( self.objectiveFunction, options ) = self.pipe.bcast ( None, root = 0 )
     self.__dict__.update ( options )
     self.g = Real1DArray ( self.objectiveFunction.NumberOfVariables ( ) ) ; self.g.Set ( 0.0 )
     if self.useBP:
         self.x = Real1DArray ( self.objectiveFunction.NumberOfVariables ( ) ) ; self.x.Set ( 0.0 )
示例#3
0
 def FromSystem(selfClass,
                system,
                electronicState1,
                electronicState2,
                method="GP"):
     """Constructor given a system."""
     # . Basic setup.
     system.electronicState = electronicState1
     self = super(SEAMObjectiveFunction, selfClass).FromSystem(system)
     self.method = method
     # . Define the first system.
     self.system1 = self.system
     # . Define the second system without coordinates.
     coordinates3 = self.system1.coordinates3
     symmetryParameters = self.system1.symmetryParameters
     self.system1.coordinates3 = None
     self.system1.symmetryParameters = None
     self.system2 = Clone(self.system1)
     self.system2.electronicState = electronicState2
     # . Reset the coordinates for both systems so that they are the same.
     self.system1.coordinates3 = coordinates3
     self.system2.coordinates3 = coordinates3
     if symmetryParameters is not None:
         self.system1.symmetryParameters = symmetryParameters
         self.system2.symmetryParameters = symmetryParameters
     # . Allocate space.
     self.g1 = Real1DArray.WithExtent(len(self))
     self.g2 = Real1DArray.WithExtent(len(self))
     # . Finish up.
     return self
示例#4
0
def WHAM_Bootstrapping(paths, **keywordArguments):
    """Solve the WHAM equations and estimate errors using bootstrapping."""
    # . Get specific options.
    options = dict(keywordArguments)
    log = options.get("log", logFile)
    minimizer = options.pop("minimizerFunction",
                            WHAM_ConjugateGradientMinimize)
    resamples = options.pop("resamples", _Default_Resamples)
    # . Initial minimization - it must succeed to proceed.
    results = minimizer(paths, **dict(options))
    if results["Converged"]:
        # . Reset options for resampling.
        options["handler"] = results.pop("Handler")
        options["histogram"] = Clone(results.pop("Unreduced Histogram"))
        options["log"] = None
        # . Resampling minimizations.
        pmfs = []
        for r in range(resamples):
            localResults = minimizer(paths, **dict(options))
            if localResults["Converged"]: pmfs.append(localResults.pop("PMF"))
        # . Process results.
        numberOfResamples = len(pmfs)
        results.update({
            "Number Of Resamples": numberOfResamples,
            "PMFs": pmfs
        })
        if numberOfResamples > 1:
            # . Gather some counters.
            lowerIndex = int(math.ceil(
                0.5 * _Alpha * float(numberOfResamples))) - 1
            upperIndex = int(
                math.floor(
                    (1.0 - 0.5 * _Alpha) * float(numberOfResamples))) - 1
            # . Do statistics.
            originalPMF = results["PMF"]
            lowerLimit = Real1DArray.WithExtent(len(originalPMF))
            standardError = Real1DArray.WithExtent(len(originalPMF))
            upperLimit = Real1DArray.WithExtent(len(originalPMF))
            work = Real1DArray.WithExtent(numberOfResamples)
            for b in range(len(originalPMF)):
                for (r, pmf) in enumerate(pmfs):
                    work[r] = pmf[b]
                work.Sort()
                m = originalPMF[b]
                lowerLimit[b] = 2.0 * m - work[upperIndex]
                upperLimit[b] = 2.0 * m - work[lowerIndex]
                standardError[b] = Statistics(work).standardDeviation
            # . Printing.
            data = (("Standard Error", standardError),
                    ("Lower 95% Confidence Interval", lowerLimit),
                    ("Upper 95% Confidence Interval", upperLimit))
            _BootstrappingSummary(results["Histogram"], log, numberOfResamples,
                                  originalPMF, standardError, lowerLimit,
                                  upperLimit)
            # . Finish up.
            for (key, value) in data:
                results[key] = value
    return results
示例#5
0
 def Initialize(self,
                pressure=_Default_Pressure,
                temperature=_Default_Temperature):
     """Create the arrays needed for the WHAM equations."""
     # . Initialization.
     handler = self.handler
     histogram = self.histogram
     if (handler is not None) and (histogram is not None):
         p0 = pressure * UNITS_PRESSURE_ATMOSPHERES_TO_KILOJOULES_PER_MOLE
         t0 = temperature * CONSTANT_MOLAR_GAS * 1.0e-3
         # . Gather pressures and temperatures.
         pressures = []
         temperatures = []
         for (p, t) in zip(handler.pressures, handler.temperatures):
             if p is None: p = pressure
             if t is None: t = temperature
             pressures.append(
                 p * UNITS_PRESSURE_ATMOSPHERES_TO_KILOJOULES_PER_MOLE)
             temperatures.append(t * CONSTANT_MOLAR_GAS * 1.0e-3)
         # . Create c which in the most general case is Exp ( - ( (Bj - B0) * U_i + (Bj*Pj - B0*P0) * V_i + Bj * SC_ji ) ).
         c = Real2DArray.WithExtents(handler.numberOfWindows,
                                     histogram.bins)
         c.Set(0.0)
         for (i, midPoint) in enumerate(histogram.BinMidPointIterator()):
             # . Energy.
             if handler.hasEnergy:
                 e = midPoint.pop(0)
                 for (j, tj) in enumerate(temperatures):
                     c[j, i] += e * (1.0 / tj - 1.0 / t0)
             # . Volume.
             if handler.hasVolume:
                 v = midPoint.pop(0)
                 for (j, pj) in enumerate(pressures):
                     c[j, i] += v * (pj / tj - p0 / t0)
             # . Soft constraints.
             for (j, tj) in enumerate(temperatures):
                 for (s, model) in zip(midPoint, handler.energyModels[j]):
                     c[j, i] += model.Energy(s)[0] / tj
         c.Scale(-1.0)
         c.Exp()
         # . Create the points arrays.
         m = Real1DArray.WithExtent(histogram.bins)
         m.Set(0.0)
         n = Real1DArray.WithExtent(handler.numberOfWindows)
         n.Set(0.0)
         for (i, v) in enumerate(histogram.counts):
             m[i] = float(v)
         for (i, v) in enumerate(handler.windowPoints):
             n[i] = float(v)
         # . Save all.
         self.pointsPerBin = m
         self.pointsPerWindow = n
         self.pressure = pressure
         self.temperature = temperature
         self.temperatureFactor = t0
         self.weightMatrix = c
示例#6
0
 def Allocate(self):
     """Allocate arrays."""
     if (self.handler is not None) and (self.histogram is not None):
         self.energies = Real1DArray.WithExtent(
             self.handler.numberOfWindows)
         self.energies.Set(1.0)
         self.probabilities = Real1DArray.WithExtent(self.histogram.bins)
         self.probabilities.Set(1.0)
         self.workE = Real1DArray.WithExtent(self.handler.numberOfWindows)
         self.workE.Set(0.0)
         self.workP = Real1DArray.WithExtent(self.histogram.bins)
         self.workP.Set(0.0)
         self.histogram.Normalize(self.probabilities)
示例#7
0
 def AtomicCharges(self,
                   qcChargeModel=None,
                   qcAtomsOnly=False,
                   spinDensities=False):
     """Calculate the partial charges for the atoms."""
     charges = None
     if self.energyModel is not None:
         em = self.energyModel
         if (em.mmModel is not None) and (not qcAtomsOnly):
             if spinDensities:
                 charges = Real1DArray.WithExtent(em.mmAtoms.size)
                 charges.Set(0.0e+00)
             else:
                 charges = em.mmAtoms.AtomicCharges()
         if em.qcModel is not None:
             qccharges = em.qcModel.AtomicCharges(
                 self.configuration,
                 chargeModel=qcChargeModel,
                 spinDensities=spinDensities)
             if charges is None:
                 charges = qccharges
             else:
                 for (index, q) in zip(em.qcAtoms, qccharges):
                     charges[index] += q
     return charges
示例#8
0
 def ParseAtomSection(self):
     """Parse the ATOM section."""
     if hasattr(self, "natoms"):
         atomicCharges = Real1DArray.WithExtent(self.natoms)
         atomicCharges.Set(0.0)
         atomicNumbers = []
         atomNames = []
         xyz = Coordinates3.WithExtent(self.natoms)
         xyz.Set(0.0)
         for i in range(self.natoms):
             items = self.GetTokens(converters=[
                 int, None, float, float, float, None, None, None, float
             ])
             if len(items) < 6:
                 self.Warning("Invalid ATOM line.", True)
             else:
                 atomicNumber = PeriodicTable.AtomicNumber(items[1])
                 if atomicNumber <= 0:
                     atomicNumber = self.AtomicNumberFromAtomType(items[5])
                 atomicNumbers.append(atomicNumber)
                 atomNames.append(items[1])
                 xyz[i, 0] = items[2]
                 xyz[i, 1] = items[3]
                 xyz[i, 2] = items[4]
                 if len(items) >= 9: atomicCharges[i] = items[8]
         self.atomicCharges = atomicCharges
         self.atomicNumbers = atomicNumbers
         self.atomNames = atomNames
         self.xyz = xyz
     else:
         self.Warning("Unknown number of atoms in molecule.", True)
示例#9
0
 def FromObjectiveFunction(selfClass,
                           objectiveFunction,
                           fixedTerminalImages=True):
     """Constructor given an objective function."""
     # . Create the object.
     self = selfClass()
     # . Set the objective function and associated data.
     if not isinstance(objectiveFunction,
                       self.__class__.objectiveFunctionClass):
         raise TypeError("Invalid objective function.")
     self.numberOfImages = objectiveFunction.NumberOfImages()
     self.numberOfImageVariables = objectiveFunction.NumberOfVariables()
     if fixedTerminalImages:
         self.numberOfVariables = (self.numberOfImages -
                                   2) * self.numberOfImageVariables
     else:
         self.numberOfVariables = self.numberOfImages * self.numberOfImageVariables
     self.objectiveFunction = objectiveFunction
     # . Read the trajectory into the path.
     self.path = ChainOfStatesPath(self.numberOfImages,
                                   self.numberOfImageVariables)
     self.path.Load(objectiveFunction)
     # . Allocate remaining space.
     self.tangent = Real1DArray(self.numberOfImageVariables)
     self.tangent.Set(0.0)
     # . Finish up.
     return self
 def PathSummary ( self, log = logFile ):
     """Output a path summary."""
     if LogFileActive ( log ):
         # . Calculate all data for the current path.
         variables = Real1DArray.WithExtent ( self.NumberOfVariables ( ) )
         self.VariablesGet ( variables )
         self.Function ( variables )
         # . Get the energies of the first and last structures.
         self.energies[0:0] = [ self.objectiveFunction.Function ( self.x0 ) ]
         self.energies.append ( self.objectiveFunction.Function ( self.xn ) )
         # . Modify the distance lists.
         self.distances1.append ( None )
         self.distances2.extend ( [ None, None ] )
         # . Output.
         table  = log.GetTable ( columns = [ 10, 20, 20, 20 ] )
         table.Start   ( )
         table.Title   ( "Path Summary" )
         table.Heading ( "Structure"    )
         table.Heading ( "Energy"       )
         table.Heading ( "Dist(i,i+1)"  )
         table.Heading ( "Dist(i,i+2)"  )
         for ( i, ( e, d1, d2 ) ) in enumerate ( zip ( self.energies, self.distances1, self.distances2 ) ):
             table.Entry ( "{:d}"  .format ( i ) )
             table.Entry ( "{:.3f}".format ( e ) )
             if d1 is None: table.Entry ( "" )
             else:          table.Entry ( "{:.3f}".format ( d1 ) )
             if d2 is None: table.Entry ( "" )
             else:          table.Entry ( "{:.3f}".format ( d2 ) )
         table.Stop ( )
    def VelocitiesAssign ( self, temperature, normalDeviateGenerator = None ):
        """Set up the velocities for the system at a particular temperature.

        If |temperature| is None the velocities must already exist.
        """
        # . Check for an existing set of velocities of the correct size.
        velocities = self.system.configuration.__dict__.get ( "velocities", None )
        QASSIGN = ( velocities is None ) or ( ( velocities is not None ) and ( len ( velocities ) != self.nvariables ) )
        # . Assign velocities.
        if QASSIGN:
            if temperature is None:
                raise ValueError ( "Velocities need to be assigned for the system but a temperature has not been specified." )
            else:
                # . Get the generator.
                if normalDeviateGenerator is None:
                    normalDeviateGenerator = NormalDeviateGenerator.WithRandomNumberGenerator ( RandomNumberGenerator.WithRandomSeed ( ) )
                # . Get the velocities.
                sigma      = _MS_TO_APS * math.sqrt ( CONSTANT_BOLTZMANN * temperature / CONSTANT_ATOMIC_MASS )
                velocities = Real1DArray.WithExtent ( self.NumberOfVariables ( ) )
                normalDeviateGenerator.NextStandardDeviates ( velocities )
                velocities.Scale ( ( sigma ) )
                self.system.configuration.velocities = velocities
        # . Project out linear constraints.
        if self.linearVectors is not None: self.linearVectors.ProjectOutOfArray ( velocities )
        # . Scale velocities if necessary (even for assigned velocities).
        if temperature is not None:
            ( ke, tactual ) = self.Temperature ( velocities )
            velocities.Scale ( math.sqrt ( temperature / tactual ) )
 def VariablesAllocate ( self ):
     """Return a variables object of the correct size."""
     if self.NumberOfVariables ( ) > 0:
         variables = Real1DArray.WithExtent ( self.NumberOfVariables ( ) )
         variables.Set ( 0.0 )
         return variables
     else:
         return None
 def VariablesAllocate ( self ):
     """Return an object to hold the variables."""
     if self.NumberOfVariables ( ) > 0:
         variables = Real1DArray.WithExtent ( self.NumberOfVariables ( ) )
         variables.Set ( 0.0 )
         return variables
     else:
         return None
示例#14
0
    def Setup ( selfClass, qcAtoms, electronicState, nbState, job, scratch, deleteJobFiles = False, useRandomJob = False, useRandomScratch = False ):
        """Set up a state given the relevant data."""
        self = selfClass ( )
        # . QC atoms.
        # . Basic attributes.
        self.charge          = electronicState.charge
        self.multiplicity    = electronicState.multiplicity
        self.numberOfQCAtoms = len ( qcAtoms )
        # . File paths.
        if useRandomJob: job = RandomString ( )
        if useRandomScratch:
            self.scratchPath = os.path.join ( scratch, RandomString ( ) )
            if not os.path.exists ( self.scratchPath ): os.mkdir ( self.scratchPath )
            self.jobPath     = os.path.join ( self.scratchPath, job )
        else:
            self.scratchPath = None
            self.jobPath     = os.path.join ( scratch, job )
        self.engradPath = self.jobPath + ".engrad"
        self.inputPath  = self.jobPath + ".inp"
        self.outputPath = self.jobPath + ".log"
	self.pcgradPath = self.jobPath + ".pcgrad"
	self.pcPath     = self.jobPath + ".pc"
        # . Options.
        self.deleteJobFiles = deleteJobFiles
        # . Symbols.
        atomicNumbers = qcAtoms.GetAtomicNumbers ( )
        self.symbols  = []
        for i in atomicNumbers:
            self.symbols.append ( PeriodicTable.Symbol ( i ) )
        # . Array attributes.
        self.qcCoordinates3  = Coordinates3.WithExtent ( self.numberOfQCAtoms ) ; self.qcCoordinates3.Set  ( 0.0 )
        self.dipole          = Vector3.Null ( )
        self.qcGradients3    = Coordinates3.WithExtent ( self.numberOfQCAtoms ) ; self.qcGradients3.Set    ( 0.0 )
        self.chelpgCharges   = Real1DArray.WithExtent  ( self.numberOfQCAtoms ) ; self.chelpgCharges.Set   ( 0.0 )
        self.lowdinCharges   = Real1DArray.WithExtent  ( self.numberOfQCAtoms ) ; self.lowdinCharges.Set   ( 0.0 )
        self.lowdinSpins     = Real1DArray.WithExtent  ( self.numberOfQCAtoms ) ; self.lowdinSpins.Set     ( 0.0 )
        self.mullikenCharges = Real1DArray.WithExtent  ( self.numberOfQCAtoms ) ; self.mullikenCharges.Set ( 0.0 )
        self.mullikenSpins   = Real1DArray.WithExtent  ( self.numberOfQCAtoms ) ; self.mullikenSpins.Set   ( 0.0 )
        # . Orbital data.
        self.H**O            = -1
        self.LUMO            = -1
        self.orbitalEnergies = []
        # . NB state.
        self.nbState = nbState
        return self
def Eigenvalues ( extent, cpuTimer, ndg ):
    s = SymmetricMatrix ( extent         ) ; s.Set ( 0.0 )
    e = Real1DArray     ( extent         ) ; e.Set ( 0.0 )
    v = Real2DArray     ( extent, extent ) ; v.Set ( 0.0 )
    for i in range ( extent ):
        for j in range ( i+1 ): s[i,j] = ndg.NextDeviate ( )
        s[i,i] *= 2.0
    tStart = cpuTimer.Current ( )
    s. Diagonalize ( e, eigenVectors = v )
    return ( cpuTimer.Current ( ) - tStart )
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
示例#17
0
 def FromOptions(selfClass,
                 alphas,
                 gradientsAlpha,
                 hessianAlpha,
                 minimumCoefficient,
                 numberOfSets=1):
     """Constructor from options."""
     self = selfClass()
     self.alphas = alphas
     self.gradientsAlpha = gradientsAlpha
     self.hessianAlpha = hessianAlpha
     self.minimumCoefficient = minimumCoefficient
     self.numberOfSets = numberOfSets
     self.numberOfVariables = len(self.alphas)
     self.numberOfVariablesPerSet = self.numberOfVariables // self.numberOfSets
     self.work = Real1DArray.WithExtent(self.numberOfVariables)
     self.workA = Real1DArray.WithExtent(self.numberOfVariables)
     self.workS = Real1DArray.WithExtent(self.numberOfVariables)
     self.workT = Real1DArray.WithExtent(self.numberOfVariables)
     return self
示例#18
0
 def GetPMF(self):
     """Calculate the PMF."""
     if (self.reducedHistogram is not None) and (self.reducedProbabilities
                                                 is not None):
         pmf = Real1DArray.WithExtent(self.reducedHistogram.bins)
         pmf.Set(0.0)
         self.reducedProbabilities.CopyTo(pmf)
         pmf.Ln()
         pmf.Scale(-self.temperatureFactor)
         v = min(pmf)
         pmf.AddScalar(-v)
         self.pmf = pmf
def _GetHardSphereRadii(atoms):
    """Get the hard-sphere radii for the atoms."""
    hsradii = Real1DArray.WithExtent(len(atoms))
    hsradii.Set(0.0)
    atomicNumbers = atoms.GetItemAttributes("atomicNumber")
    for (i, atomicNumber) in enumerate(atomicNumbers):
        try:
            hsradii[i] = _HSRADII[atomicNumber]
        except:
            raise KeyError("Hard-sphere radius for element " +
                           PeriodicTable.Symbol(atomicNumber) + " unknown.")
    return hsradii
 def DefineGrid ( self, gridspacing = _DEFAULT_GRIDSPACING, radiusfactor = _DEFAULT_RADIUSFACTOR ):
     """Define the grid."""
     if ( self.system is not None ) and ( self.system.coordinates3 is not None ) and ( self.system.energyModel is not None ) and ( self.system.energyModel.qcModel is not None ):
         self.qcCoordinates3 = self.system.energyModel.qcAtoms.GetCoordinates3 ( self.system.coordinates3, toBohrs = True )
         allRadii            = self.system.atoms.GetItemAttributes ( "vdwRadius" )
         if len ( self.qcSelection ) == len ( self.system.atoms ):
             radii = allRadii
         else:
             radii = Real1DArray ( len ( self.qcSelection ) )
             for ( i, s ) in enumerate ( self.qcSelection ):
                 radii[i] = allRadii[s]
         radii.Scale ( radiusfactor / UNITS_LENGTH_BOHRS_TO_ANGSTROMS )
         self.grid = RegularCubicGrid3 ( gridspacing, self.qcCoordinates3, radii )
 def DefineWeights ( self ):
     """Define atom weights - use masses by default."""
     self.atomWeights = self.system.atoms.GetItemAttributes ( "mass" )
     if self.nvariables > 0:
         self.variableWeights = Real1DArray.WithExtent ( self.nvariables )
         self.variableWeights.Set ( 0.0 )
         if self.freeAtoms is None: indices = range ( len ( self.system.atoms ) )
         else:                      indices = self.freeAtoms
         n = 0
         for iatom in indices:
             w = math.sqrt ( self.atomWeights[iatom] )
             for j in range ( 3 ):
                 self.variableWeights[n] = w
                 n += 1
 def FindMaxima(self, computeStructures=False):
     """Find maxima along the path."""
     if self.imageSpline is not None:
         if self.functionSplineA is None: self.BuildFunctionSplines()
         self.maximaA = self.functionSplineA.FindMaxima()
         self.maximaI = self.functionSplineI.FindMaxima()
         if computeStructures:
             structures = []
             for (s, fs) in self.maximaI:
                 v = Real1DArray.WithExtent(
                     self.imageSpline.NumberOfSplines())
                 v.Set(0.0)
                 self.imageSpline.Evaluate(s, f=v)
                 structures.append((s, fs, v))
             self.maximaIStructures = structures
示例#23
0
 def WriteBlock(self):
     """Write a block of data."""
     if self.current > 0:
         # . The following is a fudge until slicing is handled properly.
         if self.current == self.blockSize: outdata = self.data
         else:
             outdata = Real1DArray.WithExtent(self.current * self.rank)
             for i in range(len(outdata)):
                 outdata[i] = self.data[i]
         Pickle(
             os.path.join(
                 self.path,
                 _BlockPrefix + "{:d}".format(self.blocks) + _BlockPostfix),
             outdata)
         # . This is what it should be.
         #            Pickle ( os.path.join ( self.path, _BlockPrefix + "{:d}".format ( self.blocks ) + _BlockPostfix, self.data[0:self.current*self.rank] )
         self.blocks += 1
         self.current = 0
示例#24
0
 def WriteHeader(self, pressure=None, temperature=None):
     """Write the trajectory header."""
     # . Check for soft constraints.
     self.hasSoftConstraints = hasattr(
         self.owner.energyModel, "softConstraints") and (len(
             self.owner.energyModel.softConstraints) > 0)
     # . Check the volume option.
     self.hasVolume = self.hasVolume and hasattr(self.owner, "symmetry")
     # . Check that there will be data on the trajectory.
     if not (self.hasPotentialEnergy or self.hasSoftConstraints
             or self.hasVolume):
         raise ValueError("A soft-constraint trajectory contains no data.")
     # . Initialization.
     labels = []
     models = []
     # . Potential energy and volume.
     if self.hasPotentialEnergy: labels.append("Potential Energy")
     if self.hasVolume: labels.append("Volume")
     # . Soft constraints.
     if self.hasSoftConstraints:
         self.softConstraintLabels = sorted(
             self.owner.energyModel.softConstraints)
         for label in self.softConstraintLabels:
             models.append(
                 self.owner.energyModel.softConstraints[label].energyModel)
         labels.extend(self.softConstraintLabels)
     # . Set up the header.
     header = {
         "labels": labels,
         "hasPotentialEnergy": self.hasPotentialEnergy,
         "hasVolume": self.hasVolume,
         "softConstraintEnergyModels": models
     }
     # . Optional information.
     if pressure is not None: header["pressure"] = pressure
     if temperature is not None: header["temperature"] = temperature
     # . Write out.
     Pickle(os.path.join(self.path, _HeaderName + _BlockPostfix), header)
     # . Setup the block for output.
     self.rank = len(labels)
     self.data = Real1DArray.WithExtent(self.rank * self.blockSize)
示例#25
0
 def SGOFProcessMultiprocessingScript(objectiveFunction, receiver, sender):
     """Multiprocessing script."""
     # . Initialization.
     g = Real1DArray(objectiveFunction.NumberOfVariables())
     g.Set(0.0)
     # . Poll for tasks.
     while True:
         if receiver.poll():
             (task, arguments) = receiver.recv()
             if task == ProcessTaskCode_Exit:
                 break
             elif task == ProcessTaskCode_FunctionGradients:
                 try:
                     x = arguments[0]
                     f = objectiveFunction.FunctionGradients(x, g)
                     sender.send((ProcessExitCode_Success, f, g))
                 except Exception as error:
                     sender.send((ProcessExitCode_Failure, error[0]))
             else:
                 sender.send(
                     (ProcessExitCode_Failure, "Unrecognized task."))
示例#26
0
 def ParseCharges(self):
     """Parse charges from a charge analysis."""
     if (self.natoms > 0):
         nall = self.natoms + len(self.dummies)
         q = Real1DArray.WithExtent(self.natoms)
         q.Set(0.0)
         i = -1
         n = -1
         for iblock in range((nall + 4) // 5):
             self.GetLine()  # Blank line.
             self.GetLine()  # Atom heading.
             line = self.GetLine()
             tokens = line[7:].split()
             for token in tokens:
                 n += 1
                 if n not in self.dummies:
                     i += 1
                     q[i] = float(token)
         return q
     else:
         return None
示例#27
0
 def GetItemAttributes(self,
                       attributeLabel,
                       asDictionary=False,
                       selection=None):
     """Return a sequence of item attributes."""
     # . Initialization.
     data = None
     if (attributeLabel
             in Atom.defaultAttributes) or (attributeLabel
                                            in Element.defaultAttributes):
         if selection is None: indices = range(len(self))
         else: indices = selection
         if indices is not None:
             # . Use a dictionary for non-default values only.
             if asDictionary:
                 data = {}
                 if attributeLabel in Atom.defaultAttributes:
                     defaultValue = Atom.defaultAttributes[attributeLabel]
                 else:
                     defaultValue = Element.defaultAttributes[
                         attributeLabel]
                 for i in indices:
                     value = getattr(self[i], attributeLabel)
                     if value != defaultValue: data[i] = value
             # . Use a sequence for all values.
             else:
                 attribute = getattr(self[0], attributeLabel)
                 # . Float attribute.
                 if isinstance(attribute, (float)):
                     data = Real1DArray.WithExtent(len(indices))
                     for (i, index) in enumerate(indices):
                         data[i] = getattr(self[index], attributeLabel)
                 # . Other attribute.
                 else:
                     data = []
                     for i in indices:
                         data.append(getattr(self[i], attributeLabel))
     return data
 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 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
示例#30
0
def JaguarBondOrders(infile,
                     outfile,
                     bondOrdertolerance=_DEFAULTBONDORDERTOLERANCE,
                     chargetolerance=_DEFAULTCHARGETOLERANCE,
                     log=logFile,
                     QCROSS=False):
    """Calculate bond orders given Jaguar input and output files."""

    # . Parse the input file.
    infile = JaguarInputFileReader(infile)
    infile.Parse()
    infile.Summary(log=logFile)

    # . Parse the output file.
    outfile = JaguarOutputFileReader(outfile)
    outfile.Parse()
    outfile.Summary(log=logFile)

    # . Get data from the files.
    # . Input.
    atomicNumbersi = getattr(infile, "atomicNumbers", None)
    coordinates3 = getattr(infile, "coordinates3", None)
    orbitalsets = getattr(infile, "orbitalsets", None)

    # . Output.
    atomicNumberso = getattr(outfile, "atomicNumbers", None)
    nfunctions = getattr(outfile, "nfunctions", None)
    overlap = getattr(outfile, "overlap", None)

    # . Check for coordinates.
    if coordinates3 is None:
        raise ValueError("The coordinate data is missing from the input file.")

    # . Check the orbital data.
    QOK = (orbitalsets is not None) and (len(orbitalsets) > 0)
    if QOK:
        if (len(orbitalsets) == 1) and ("" in orbitalsets):
            spinDensitiesRESTRICTED = True
        elif (len(orbitalsets)
              == 2) and ("alpha" in orbitalsets) and ("beta" in orbitalsets):
            spinDensitiesRESTRICTED = False
        else:
            QOK = False
    if not QOK: raise ValueError("Invalid orbital data on input file.")
    if spinDensitiesRESTRICTED: nbasisi = infile.orbitalsets[""][1]
    else: nbasisi = infile.orbitalsets["alpha"][1]

    # . Check the overlap.
    if (overlap is None):
        raise ValueError("The overlap matrix is missing from the output file.")
    nbasiso = overlap.Dimension()

    # . Check the array giving the number of functions per atom.
    #    print nfunctions, len ( nfunctions ), len ( atomicNumberso ), sum ( nfunctions ), nbasiso
    if (nfunctions is None) or (len(nfunctions) != len(atomicNumberso) or
                                (sum(nfunctions) != nbasiso)):
        raise ValueError(
            "Basis function data on the output file is missing or invalid.")

    # . Create the function index array.
    findices = []
    first = 0
    last = 0
    for f in nfunctions:
        last += f
        findices.append((first, last))
        first += f

    # . Check for compatibility between the data.
    QOK = (atomicNumbersi is not None) and (atomicNumberso is not None) and (
        len(atomicNumbersi) == len(atomicNumberso)) and (nbasisi == nbasiso)
    if QOK:
        for (i, j) in zip(atomicNumbersi, atomicNumberso):
            if i != j:
                QOK = False
                break
    if not QOK:
        raise ValueError(
            "The systems on the input and output files are incompatible.")

    # . Set the keys for the calculation.
    if spinDensitiesRESTRICTED: keys = [""]
    else: keys = ["alpha", "beta"]

    # . Get the densities multiplied by the overlap.
    ps = {}
    for key in keys:
        p = _MakeDensity(orbitalsets[key])
        #        p.Print ( title = "**1**" )
        result = Real2DArray.WithExtents(nbasisi, nbasisi)
        result.Set(999.0)
        p.PostMultiply(overlap, result)
        #        overlap.Print ( title = "**2**" )
        #        result.Print ( title = "**3**" )
        ps[key] = result
#    f = STOP
# . Scale ps correctly for the spin-restricted case.
    if spinDensitiesRESTRICTED: ps[""].Scale(2.0)

    # . If cross terms are not required condense the ps matrices.
    if (not QCROSS) and (not spinDensitiesRESTRICTED):
        tps = ps.pop(keys[0])
        for key in keys[1:]:
            tps.AddScaledMatrix(1.0, ps[key])
        ps = {"": tps}
        keys = [""]

    # . Get the bond-orders.
    bondOrders = {}
    for key1 in keys:
        for key2 in keys:
            bondOrders[(key1, key2)] = _MakeBondOrders(ps[key1], ps[key2],
                                                       findices)

    # . Make the total bond-order if necessary.
    bokeys = bondOrders.keys()
    if len(bokeys) > 1:
        bokeys.sort()
        tbo = Clone(bondOrders[bokeys[0]])
        for key in bokeys[1:]:
            tbo.AddScaledMatrix(1.0, bondOrders[key])
        tkey = ("", "")
        bokeys.append(tkey)
        bondOrders[tkey] = tbo

    # . Compute the electronic contribution to the Mulliken charges.
    qmulliken = Real1DArray.WithExtent(len(atomicNumbersi))
    qmulliken.Set(0.0)
    for key in keys:
        _MakeElectronicMullikenCharges(ps[key], findices, qmulliken)

    # . Determine atom valencies.
    free = Real1DArray.WithExtent(len(atomicNumbersi))
    free.Set(0.0)
    valencies = Real1DArray.WithExtent(len(atomicNumbersi))
    valencies.Set(0.0)
    tbo = bondOrders[("", "")]
    for i in range(len(atomicNumbersi)):
        valencies[i] = (-2.0 * qmulliken[i]) - tbo[i, i]
        totalbo = 0.0
        for j in range(len(atomicNumbersi)):
            totalbo += tbo[i, j]
        free[i] = (-2.0 * qmulliken[i]) - totalbo

    # . Add in the core contributions to the Mulliken charges.
    for (i, q) in enumerate(atomicNumbersi):
        qmulliken[i] += float(q)
    if outfile.QECP:
        for (i, q) in enumerate(outfile.ecpelectrons):
            qmulliken[i] -= float(q)

    # . Output the results.
    if LogFileActive(log):

        # . Get the spin label.
        if spinDensitiesRESTRICTED: spinlabel = "Spin Restricted"
        else: spinlabel = "Spin Unrestricted"

        # . Create the atom names.
        atomnames = []
        for (i, n) in enumerate(atomicNumbersi):
            atomnames.append(PeriodicTable.Symbol(n, index=i + 1))

        # . Atom data.
        columns = [10, 20, 20, 20]
        if not spinDensitiesRESTRICTED: columns.append(20)
        table = log.GetTable(columns=columns)
        table.Start()
        table.Title("Atom Data (" + spinlabel + ")")
        table.Heading("Atom")
        table.Heading("Charge")
        table.Heading("Self Bond Order")
        table.Heading("Valence")
        if not spinDensitiesRESTRICTED: table.Heading("Free Valence")
        for (i, ni) in enumerate(atomnames):
            table.Entry(ni)
            table.Entry("{:.3f}".format(qmulliken[i]))
            table.Entry("{:.3f}".format(tbo[i, i]))
            table.Entry("{:.3f}".format(valencies[i]))
            if not spinDensitiesRESTRICTED:
                table.Entry("{:.3f}".format(free[i]))
        table.Stop()

        # . Bond orders.
        for key in bokeys:
            orders = bondOrders[key]
            table = log.GetTable(columns=[10, 10, 20, 20])
            table.Start()
            if key == ("", ""): table.Title("Total Bond Orders")
            else:
                table.Title(key[0].title() + "/" + key[1].title() +
                            " Bond Orders")
            table.Heading("Atom 1")
            table.Heading("Atom 2")
            table.Heading("Order")
            table.Heading("Distance")
            for (i, ni) in enumerate(atomnames):
                for (j, nj) in enumerate(atomnames[0:i]):
                    b = orders[i, j]
                    if math.fabs(b) > bondOrdertolerance:
                        table.Entry(ni)
                        table.Entry(nj)
                        table.Entry("{:.3f}".format(b))
                        table.Entry("{:.3f}".format(coordinates3.Distance(
                            i, j)))
            table.Stop()

        # . Checks on the calculation.
        # . Free valence.
        if spinDensitiesRESTRICTED:
            deviation = free.AbsoluteMaximum()
            if deviation > chargetolerance:
                log.Paragraph(
                    "Warning: the largest deviation between the free valence values and zero is {:.3f}."
                    .format(deviation))

        # . Total charge.
        deviation = math.fabs(qmulliken.Sum() - float(infile.charge))
        if deviation > chargetolerance:
            log.Paragraph(
                "Warning: the total charge deviates from the formal charge by {:.3f}."
                .format(deviation))

        # . Check for a valid reference set of Mulliken charges.
        qreference = getattr(outfile, "qmulliken", None)
        if (qreference is not None) and (len(qreference)
                                         == len(atomicNumbersi)):
            qmulliken.AddScaledArray(-1.0, qreference)
            deviation = qmulliken.AbsoluteMaximum()
            if deviation > chargetolerance:
                log.Paragraph(
                    "Warning: the largest deviation between calculated and read Mulliken charges is {:.3f}."
                    .format(deviation))

    # . Finish up.
    return bondOrders