Exemple #1
0
def example_1():
    # In this example, we will generate a smooth CNH-HCN isomerization
    # guessed pathway

    # Step 1 - Generate the bad initial guess
    print("Step 1 - Generate the bad initial guess...")
    H_coords = [(2, 0), (2, 1), (1, 1), (0, 1), (-1, 1), (-1, 0)]
    CNH_frames = [[
        structures.Atom("C", 0, 0, 0),
        structures.Atom("N", 1, 0, 0),
        structures.Atom("H", x, y, 0)
    ] for x, y in H_coords]
    # Further, randomly rotate the atoms
    CNH_frames = [
        geometry.perturbate(frame, dx=0.0, dr=360) for frame in CNH_frames
    ]
    files.write_xyz(CNH_frames, "rotated_pathway.xyz")

    # Step 2 - Use procrustes to remove rotations
    print("Step 2 - Use Procrustes to remove rotations...")
    geometry.procrustes(CNH_frames)
    files.write_xyz(CNH_frames, "procrustes_pathway.xyz")

    # Step 3 - Smooth out the band by minimizing the RMS atomic motion between
    # consecutive frames until it is below 0.1 (with a max of 50 frames).
    print("Step 3 - Smooth out the band...")
    CNH_frames = geometry.smooth_xyz(CNH_frames,
                                     R_max=0.1,
                                     F_max=50,
                                     use_procrustes=True)
    # Save smoothed band
    files.write_xyz(CNH_frames, "smoothed_pathway.xyz")
Exemple #2
0
    rmax = float(argv[argv.index('-rmax') + 1])

if "-fmax" in argv[2:]:
    fmax = int(argv[argv.index('-fmax') + 1])

frames = files.read_xyz(path + file_name + ".xyz")

if interpolate:
    frames_hold = [copy.deepcopy(f) for f in frames]
    if b_start is not None:
        frames = frames[b_start:b_stop]
    frames = geometry.smooth_xyz(frames,
                                 R_MAX=rmax,
                                 F_MAX=fmax,
                                 PROCRUSTES=True,
                                 N_FRAMES=nframes)
    if b_start is not None:
        a = frames_hold[:b_start]
        b = frames
        c = frames_hold[b_stop - 1:]
        if not isinstance(a[0], list):
            a = [a]
        if not isinstance(b[0], list):
            b = [b]
        if not isinstance(c[0], list):
            c = [c]
        frames = a + b + c

_ = geometry.procrustes(frames)
files.write_xyz(frames, path + file_name + append + ".xyz")
Exemple #3
0
# First we want to read in the manually made iterations
fptrs = [int(f.split(".xyz")[0]) for f in os.listdir("reaction_coordinate")]
fptrs.sort()

# Now, we loop through all files in numerical order and append to our reaction coordinate
rxn = []
for f in fptrs:
    rxn.append(files.read_xyz("reaction_coordinate/%d.xyz" % f))

# Save an example of this rough reaction we made
files.write_xyz(rxn, "reaction_coordinate_rough")

# Now, we smooth it out.  There are many ways of doing so.  We'll only show the main two methods here
# Here we just make a copy of the frames for the second method
held_rough_reaction = copy.deepcopy(rxn)

# Method 1 - Procrustes to minimize rotations and translations between consecutive frames
geometry.procrustes(rxn)
files.write_xyz(rxn, "reaction_coordinate_procrustes")

# Method 2 - Procrustes plus linear interpolation
# Note, R_MAX is the maximum average change in atomic positions between adjacent frames (in angstroms)
#       F_MAX is the maximum number of frames we want in the final reaction coordinate
rxn = copy.deepcopy(held_rough_reaction)  # Grab the previously rough reaction
geometry.smooth_xyz(rxn,
                    R_MAX=0.1,
                    F_MAX=50,
                    PROCRUSTES=True,
                    outName="reaction_coordinate_smooth",
                    write_xyz=True)
Exemple #4
0
def procrustes():
    # Default Documentation
    help_info = '''
procrustes
---------
A command line tool to run procrustes along an xyz file.

procrustes [file.xyz] [Options]

    Flag            Default         Description
-help, -h        :            :  Print this help menu
-overwrite, -o   :            :  Overwrite the initial file
-append, -a      :   _proc    :  Change the appended name alteration
-interpolate, -i :            :  This will turn on linear interpolation
-rmax            :    0.5     :  The default max rms for interpolation
-fmax            :     25     :  The default max number of frames for
                                 interpolation
-nframes, -n     :            :  If specified, interpolate to exactly n
                                 frames.
-between, -b     :            :  If specified, then interpolation is only
                                 run between the two frames.  Note, this
                                 is [x, y) inclusive.

Default behaviour is to use procrustes on an xyz to best align
the coordinates, and then to save a new xyz file with the name
OLD_proc.xyz (where OLD is the original xyz file name).

NOTE! If you specify -o and -a, then appending will occur instead
of overwritting.

Ex.

procrustes demo.xyz
procrustes demo.xyz -i -n 20
procrustes demo.xyz -i -rmax 0.1 -fmax 30
procrustes demo.xyz -i -b 5 8 -n 6
'''

    # Parse Arguments
    if '-h' in argv or '-help' in argv or len(argv) < 2:
        print(help_info)
        exit()

    # Parse Arguments
    append = "_proc"

    path = os.getcwd()
    if not path.endswith("/"):
        path += "/"

    file_name = argv[1]
    interpolate = False
    rmax = 0.5
    fmax = 25
    nframes = None
    b_start, b_stop = None, None

    if ".xyz" in file_name:
        file_name = file_name.split(".xyz")[0]

    if "-o" in argv[2:]:
        append = ""
    elif "-overwrite" in argv[2:]:
        append = ""

    if "-i" in argv[2:]:
        interpolate = True
    elif "-interpolate" in argv[2:]:
        interpolate = True

    if "-a" in argv[2:]:
        append = argv[argv.index('-a') + 1]
    elif "-append" in argv[2:]:
        append = argv[argv.index('-append') + 1]

    if "-n" in argv[2:]:
        nframes = int(argv[argv.index('-n') + 1])
    elif "-nframes" in argv[2:]:
        nframes = int(argv[argv.index('-nframes') + 1])

    if "-b" in argv[2:]:
        b_start = int(argv[argv.index('-b') + 1])
        b_stop = int(argv[argv.index('-b') + 2])
    elif "-between" in argv[2:]:
        b_start = int(argv[argv.index('-between') + 1])
        b_stop = int(argv[argv.index('-between') + 2])

        assert b_start >= 0, "b_start must be >= 0."
        assert b_stop >= 2 + b_start, "b_stop must be >= 2 + b_start."

    if "-rmax" in argv[2:]:
        rmax = float(argv[argv.index('-rmax') + 1])

    if "-fmax" in argv[2:]:
        fmax = int(argv[argv.index('-fmax') + 1])

    frames = files.read_xyz(path + file_name + ".xyz")

    if interpolate:
        frames_hold = [copy.deepcopy(f) for f in frames]
        if b_start is not None:
            frames = frames[b_start:b_stop]
        frames = geometry.smooth_xyz(frames,
                                     R_max=rmax,
                                     F_max=fmax,
                                     N_frames=nframes,
                                     use_procrustes=True)
        if b_start is not None:
            a = frames_hold[:b_start]
            b = frames
            c = frames_hold[b_stop - 1:]
            if not isinstance(a[0], list):
                a = [a]
            if not isinstance(b[0], list):
                b = [b]
            if not isinstance(c[0], list):
                c = [c]
            frames = a + b + c

    _ = geometry.procrustes(frames)
    files.write_xyz(frames, path + file_name + append + ".xyz")
Exemple #5
0
    def align_coordinates(self, r, B=None, H=None, return_matrix=False):
        '''
        Get a rotation matrix A that will remove rigid rotation from the
        new coordinates r.  Further, if another vector needs rotating by the
        same matrix A, it should be passed in B and will be rotated.  If
        a matrix also needs rotating, it can be passed as H and also be
        rotated.

        *Parameters*

            r: *list, float*
                1D array of atomic coordinates to be rotated by procrustes
                matrix A.
            B: *list, list, float, optional*
                A list of vectors that may also be rotated by the same matrix
                as *r*.
            H: *list, list, float, optional*
                A matrix that should also be rotated via:
                    H = R * H * R.T
            return_matrix: *bool, optional*
                Whether to also return the rotation matrix used or not.

        *Returns*

            rotations: *dict*
                A dictionary holding 'A', the rotation matrix, 'r', the
                rotated new coordinates, 'B', a list of all other vectors that
                were rotated, and 'H', a rotated matrix.
        '''
        # Prevent rotation or translation
        coord_count = 0
        st = self.states
        for s in st[1:-1]:
            for a in s:
                a.x, a.y, a.z = r[coord_count:coord_count + 3]
                coord_count += 3

        # Translate and rotate each frame to fit its neighbor
        # Note, procrustes will change st[-1] which is fine as we need this
        # for spring force calculations
        A = geometry.procrustes(st)

        coord_count = 0
        for s in st[1:-1]:
            for a in s:
                r[coord_count:coord_count + 3] = [a.x, a.y, a.z]
                coord_count += 3

        C = []
        R = block_diag(*A[0:-len(st[0])])
        if B is not None:
            for b in B:
                # Validation code that a 1D array here works the same way.
                # shape = b.shape
                # b2 = b.flatten().dot(R)
                # C.append(b2.reshape(shape))
                C.append(np.dot(b, R))
        if C == []:
            C = None
        if H is not None:
            # Note, to transform the Hessian matrix, it's not like a normal
            # vector (as above)
            H = R * H * R.T

        return_this = {'A': A,
                       'r': r,
                       'B': C,
                       'H': H}

        return return_this
Exemple #6
0
    def __init__(self,
                 name, states, theory, extra_section='',
                 initial_guess=None, spring_atoms=None,
                 nprocs=1, queue=None, mem=2000, priority=None,
                 disp=0,
                 k=0.00367453,  # 0.1 eV/A in Ha/A
                 charge=0,
                 multiplicity=1,
                 fit_rigid=True,
                 DFT='orca', opt='LBFGS',
                 start_job=None, get_results=None,
                 new_opt_params={},
                 callback=None,
                 ci_neb=False,
                 ci_N=5,
                 no_energy=False):
        self.name = name
        self.states = states
        self.theory = theory
        self.extra_section = extra_section
        self.initial_guess = initial_guess
        self.spring_atoms = spring_atoms

        self.nprocs = nprocs
        self.queue = queue
        self.mem = mem
        self.priority = priority

        self.disp = disp
        self.k = k
        self.charge = charge
        self.multiplicity = multiplicity
        self.DFT = DFT
        self.opt = opt.lower()
        self.fit_rigid = fit_rigid
        self.start_job = start_job
        self.get_results = get_results

        self.ci_neb = ci_neb
        self.ci_img = None
        self.ci_N = ci_N

        # These are variables to make life easier on the user after NEB runs
        self.last_iteration_run = None
        self.highest_energy_frame_index = None

        self.no_energy = no_energy

        self.new_opt_params = new_opt_params
        if 'fit_rigid' not in new_opt_params:
            new_opt_params['fit_rigid'] = fit_rigid

        # Other starting parameters
        self.prv_RMS = None
        self.prv_MAX = None
        self.prv_MAX_E = None
        self.nframes = len(states)
        self.RMS_force = float('inf')
        self.MAX_force = float('inf')
        self.MAX_energy = float('inf')
        self.step = 0
        self.calls_to_force = 0
        self.calls_to_calculate = 0

        self.callback = callback

        self.job_hang_time = None
        self.DFT = DFT.lower().strip()
        if self.DFT == 'orca':
            self.start_job = orca_start_job
            self.get_results = orca_results
        if self.DFT == 'g09':
            self.start_job = g09_start_job
            self.get_results = g09_results

        if (self.start_job is None or
                self.get_results is None):
            raise Exception("Error - You need to either specify DFT as orca or \
g09.  If not, you need to manually specify start_job and get_results.")

        # In all cases, optimize the path via rigid rotations first
        # Set to only if fit_rigid for comparison purposes
        if self.fit_rigid:
            geometry.procrustes(self.states)

        # Load initial coordinates into flat array for optimizer
        self.coords_start = []
        for s in states[1:-1]:
            for a in s:
                self.coords_start += [a.x, a.y, a.z]

        # Raise warnings if odd starting parameters used
        if self.ci_neb and "linesearch" in self.new_opt_params and self.new_opt_params["linesearch"] is not None:
            print("\nWARNING\nYou have chosen to have climbing image with a linesearch.")
            print("It is recommended to set linesearch to None, as at times this prevents the climbing image to")
            print("increase the energy as needed.")
        elif self.ci_neb and "linesearch" not in self.new_opt_params and self.opt in ["BFGS", "LBFGS", "CG", "SD"]:
            print("\nWARNING\nYou have chosen to have climbing image.  Beware that the default parameters for the")
            print("optimizer you chose may have a linesearch set.  It is recommended to set linesearch to None,")
            print("as at times this prevents the climbing image to increase the energy as needed.")

        if self.ci_neb and self.no_energy:
            raise Exception("\nERROR\nUnable to do climbing image without energy. Let no_energy be False.")
Exemple #7
0
    def __init__(self,
                 name, states, theory, extra_section='', charge=0,
                 initial_guess=None, spring_atoms=None,
                 procs=1, queue=None, mem=2000, priority=None,
                 disp=0,
                 k_max=0.1837, gamma=0.2,
                 fit_rigid=True,
                 DFT='orca', opt='LBFGS',
                 start_job=None, get_results=None,
                 new_opt_params={},
                 callback=None):
        self.name = name
        self.states = states
        self.theory = theory
        self.extra_section = extra_section
        self.charge = charge
        self.initial_guess = initial_guess
        self.spring_atoms = spring_atoms

        self.procs = procs
        self.queue = queue
        self.mem = mem
        self.priority = priority

        self.disp = disp
        self.peak = 0
        self.k_max = k_max
        self.k = []
        self.gamma = gamma
        self.DFT = DFT
        self.opt = opt.lower()
        self.fit_rigid = fit_rigid
        self.start_job = start_job
        self.get_results = get_results

        self.new_opt_params = new_opt_params
        if 'fit_rigid' not in new_opt_params:
            new_opt_params['fit_rigid'] = fit_rigid

        # Other starting parameters
        self.prv_RMS = None
        self.prv_MAX = None
        self.prv_MAX_E = None
        self.nframes = len(states)
        self.RMS_force = float('inf')
        self.MAX_force = float('inf')
        self.MAX_energy = float('inf')
        self.step = 0
        self.initialize = True
        self.calls_to_calculate = 0

        self.callback = callback

        self.DFT = DFT.lower().strip()
        if self.DFT == 'orca':
            self.start_job = orca_start_job
            self.get_results = orca_results
        if self.DFT == 'g09':
            self.start_job = g09_start_job
            self.get_results = g09_results

        if (self.start_job is None or
                self.get_results is None):
            raise Exception("Error - You need to either specify DFT as orca or \
g09.  If not, you need to manually specify start_job and get_results.")

        # In all cases, optimize the path via rigid rotations first
        # Set to only if fit_rigid for comparison purposes
        if self.fit_rigid:
            geometry.procrustes(self.states)

        # Load initial coordinates into flat array for optimizer
        self.coords_start = []
        for s in states[1:-1]:
            for a in s:
                self.coords_start += [a.x, a.y, a.z]
Exemple #8
0
    def __init__(
            self,
            name,
            states,
            theory,
            extra_section='',
            initial_guess=None,
            spring_atoms=None,
            procs=1,
            queue=None,
            mem=2000,
            priority=None,
            disp=0,
            k=0.00367453,  # 0.1 eV/A in Ha/A
            charge=0,
            fit_rigid=True,
            DFT='orca',
            opt='LBFGS',
            start_job=None,
            get_results=None,
            new_opt_params={},
            new_auto_opt_params={},
            callback=None,
            ci_ANEB=False,
            ci_N=5,
            ANEB_Nsim=5,
            ANEB_Nmax=15,
            add_by_energy=False):
        self.name = name
        self.states = states
        self.all_states = copy.deepcopy(self.states)
        self.theory = theory
        self.extra_section = extra_section
        self.initial_guess = initial_guess
        self.spring_atoms = spring_atoms

        self.procs = procs
        self.queue = queue
        self.mem = mem
        self.priority = priority

        self.disp = disp
        self.k = [k for i in states[:-1]]
        self.k_all = copy.deepcopy(self.k)
        self.k_0 = k
        self.charge = charge
        self.DFT = DFT
        self.opt = opt.lower()
        self.fit_rigid = fit_rigid
        self.start_job = start_job
        self.get_results = get_results

        self.ci_ANEB = ci_ANEB
        self.ci_img = None
        self.ci_N = ci_N

        self.add_by_energy = add_by_energy

        self.ANEB_Nsim = ANEB_Nsim
        self.ANEB_Nmax = ANEB_Nmax
        self.energy_gaps = None

        self.debug = False

        self.new_opt_params = new_opt_params
        if 'fit_rigid' not in new_opt_params:
            new_opt_params['fit_rigid'] = fit_rigid

        self.new_auto_opt_params = new_auto_opt_params
        if 'fit_rigid' not in new_auto_opt_params:
            new_auto_opt_params['fit_rigid'] = fit_rigid

        # Other starting parameters
        self.prv_RMS = None
        self.prv_MAX = None
        self.prv_MAX_E = None
        self.nframes = len(states)
        self.RMS_force = float('inf')
        self.MAX_force = float('inf')
        self.MAX_energy = float('inf')
        self.step = 0
        self.calls_to_calculate = 0
        self.calls_to_force = 0

        self.callback = callback

        self.DFT = DFT.lower().strip()
        if self.DFT == 'orca':
            self.start_job = orca_start_job
            self.get_results = orca_results
        if self.DFT == 'g09':
            self.start_job = g09_start_job
            self.get_results = g09_results

        if (self.start_job is None or self.get_results is None):
            raise Exception(
                "Error - You need to either specify DFT as orca or \
g09.  If not, you need to manually specify start_job and get_results.")

        # Ensure we have ANEB_Nsim at minimum
        while len(self.states) < self.ANEB_Nsim:
            add_frame(self)
            if self.fit_rigid:
                geometry.procrustes(self.states)

        # In all cases, optimize the path via rigid rotations first
        # Set to only if fit_rigid for comparison purposes
        if self.fit_rigid:
            geometry.procrustes(self.states)

        self.all_states = copy.deepcopy(self.states)

        # Load initial coordinates into flat array for optimizer
        self.flattened_states = flattened(self.states)

        # Raise warnings if odd starting parameters used
        if self.ci_ANEB and "linesearch" in self.new_opt_params and self.new_opt_params[
                "linesearch"] is not None:
            print(
                "\nWARNING\nYou have chosen to have climbing image with a linesearch."
            )
            print(
                "It is recommended to set linesearch to None, as at times this prevents the climbing image to"
            )
            print("increase the energy as needed.")
        elif self.ci_ANEB and "linesearch" not in self.new_opt_params and self.opt in [
                "BFGS", "LBFGS", "CG", "SD"
        ]:
            print(
                "\nWARNING\nYou have chosen to have climbing image.  Beware that the default parameters for the"
            )
            print(
                "optimizer you chose may have a linesearch set.  It is recommended to set linesearch to None,"
            )
            print(
                "as at times this prevents the climbing image to increase the energy as needed."
            )