Beispiel #1
0
def test_dihedral_scanner_range_masks():
    """
    Test dihedral scanner range limit implemented as masks
    """
    # setup a scanner
    m = Molecule()
    m.elem = ['H'] * 5
    m.xyzs = [
        np.array([[0, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 1], [1, 0, 0]],
                 dtype=float) * 0.5
    ]
    m.build_topology()
    engine = EngineBlank()
    dihedrals = [[0, 1, 2, 3], [1, 2, 3, 4]]
    # two ranges are tested, one is normal, one is "split" crossing boundaries
    dihedral_ranges = [[-120, 120], [150, 240]]
    scanner = DihedralScanner(engine,
                              dihedrals=dihedrals,
                              grid_spacing=[30, 30],
                              init_coords_M=m,
                              dihedral_ranges=dihedral_ranges)
    # check dihedral masks
    assert scanner.dihedral_ranges == dihedral_ranges
    assert scanner.dihedral_mask[0] == {
        -120, -90, -60, -30, 0, 30, 60, 90, 120
    }
    assert scanner.dihedral_mask[1] == {-150, -120, 150, 180}
    # test validate_task() function
    task1 = (m, (-120, 120), (-120, 150))
    assert scanner.validate_task(task1) == True
    task2 = (m, (-120, 60), (-120, 90))
    assert scanner.validate_task(task2) == False
Beispiel #2
0
def test_dihedral_scanner_energy_upper_limit_filter():
    """
    Test dihedral scanner energy_upper_limit as task filters
    """
    # setup a scanner
    m = Molecule()
    m.elem = ['H'] * 5
    m.xyzs = [
        np.array([[0, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 1], [1, 0, 0]],
                 dtype=float) * 0.5
    ]
    m.build_topology()
    engine = EngineBlank()
    dihedrals = [[0, 1, 2, 3], [1, 2, 3, 4]]
    # two ranges are tested, one is normal, one is "split" crossing boundaries
    dihedral_ranges = [[-120, 120], [150, 240]]
    scanner = DihedralScanner(engine,
                              dihedrals=dihedrals,
                              grid_spacing=[30, 30],
                              init_coords_M=m,
                              dihedral_ranges=dihedral_ranges,
                              energy_upper_limit=0.001)
    # check dihedral masks
    assert scanner.energy_upper_limit == 0.001
    # test validate_task() function
    scanner.global_minimum_energy = 0.0
    m.qm_energies = [0.0]
    task1 = (m, (-120, 120), (-120, 150))
    assert scanner.validate_task(task1) == True
    m.qm_energies = [0.0015]
    task2 = (m, (-120, 120), (-120, 150))
    assert scanner.validate_task(task2) == False
Beispiel #3
0
def test_stack_psi4():
    """
    Test the stack of torsiondrive -> geomeTRIC -> qcengine -> Psi4
    """
    orig_path = os.getcwd()
    this_file_folder = os.path.dirname(os.path.realpath(__file__))
    test_folder = os.path.join(this_file_folder, 'files', 'hooh-psi4')
    os.chdir(test_folder)

    # Make sure to delete subfolders
    opt_tmp_folder = os.path.join(test_folder, "opt_tmp")
    shutil.rmtree(opt_tmp_folder, ignore_errors=True)

    engine = Psi4QCEngineEngine('start.xyz')
    scanner = DihedralScanner(engine,
                              dihedrals=[[0, 1, 2, 3]],
                              grid_spacing=[90],
                              verbose=True)
    scanner.master()
    result_energies = [
        scanner.grid_energies[grid_id]
        for grid_id in sorted(scanner.grid_energies.keys())
    ]
    assert np.allclose(
        result_energies,
        [-151.17367357, -151.16167615, -151.17367357, -151.17370632],
        atol=1e-4)
    os.chdir(orig_path)
Beispiel #4
0
def main():
    import argparse, sys
    parser = argparse.ArgumentParser(description="Potential energy scan of dihedral angle from 1 to 360 degree", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('inputfile', type=str, help='Input template file for QMEngine. Geometry will be used as starting point for scanning.')
    parser.add_argument('dihedralfile', type=str, help='File defining all dihedral angles to be scanned.')
    parser.add_argument('--init_coords', type=str, help='File contain a list of geometries, that will be used as multiple starting points, overwriting the geometry in input file.')
    parser.add_argument('-g', '--grid_spacing', type=int, nargs='*', default=[15], help='Grid spacing for dihedral scan, i.e. every 15 degrees, multiple values will be mapped to each dihedral angle')
    parser.add_argument('-e', '--engine', type=str, default="psi4", choices=['qchem', 'psi4', 'terachem', 'openmm', "gaussian"], help='Engine for running scan')
    parser.add_argument('-c', '--constraints', type=str, default=None, help='Provide a constraints file in geomeTRIC format for additional freeze or set constraints (geomeTRIC or TeraChem only)')
    parser.add_argument('--native_opt', action='store_true', default=False, help='Use QM program native constrained optimization algorithm. This will turn off geomeTRIC package.')
    parser.add_argument('--energy_thresh', type=float, default=1e-5, help='Only activate grid points if the new optimization is <thre> lower than the previous lowest energy (in a.u.).')
    parser.add_argument('--energy_upper_limit', type=float, default=None, help='Only activate grid points if the new optimization is less than <thre> higher than the global lowest energy (in a.u.).')
    parser.add_argument('--wq_port', type=int, default=None, help='Specify port number to use Work Queue to distribute optimization jobs.')
    parser.add_argument('--zero_based_numbering', action='store_true', help='Use zero_based_numbering in dihedrals file.')
    parser.add_argument('-v', '--verbose', action='store_true', default=False, help='Print more information while running.')
    args = parser.parse_args()

    # print input command for reproducibility
    print(' '.join(sys.argv))

    # parse the dihedral file
    if args.zero_based_numbering is True:
        print("The use of command line --zero_based_numbering is deprecated and will be removed in the future. Please use #zero_based_numbering in dihedralfile")
    dihedral_idxs, dihedral_ranges = load_dihedralfile(args.dihedralfile, args.zero_based_numbering)
    grid_dim = len(dihedral_idxs)

    # parse additional constraints
    constraints_dict = None
    if args.constraints is not None:
        with open(args.constraints) as fin:
            constraints_dict = make_constraints_dict(fin.read())
            # check if there are extra constraints conflict with the specified dihedral angles
            check_conflict_constraints(constraints_dict, dihedral_idxs)

    # format grid spacing
    n_grid_spacing = len(args.grid_spacing)
    if n_grid_spacing == grid_dim:
        grid_spacing = args.grid_spacing
    elif n_grid_spacing == 1:
        grid_spacing = args.grid_spacing * grid_dim
    else:
        raise ValueError("Number of grid_spacing values %d is not consistent with number of dihedral angles %d" % (grid_dim, n_grid_spacing))

    # create QM Engine, and WorkQueue object if provided port
    engine = create_engine(args.engine, inputfile=args.inputfile, work_queue_port=args.wq_port, native_opt=args.native_opt)

    # load init_coords if provided
    init_coords_M = Molecule(args.init_coords) if args.init_coords else None

    # create DihedralScanner object
    scanner = DihedralScanner(engine, dihedrals=dihedral_idxs, dihedral_ranges=dihedral_ranges, grid_spacing=grid_spacing, init_coords_M=init_coords_M,
                              energy_decrease_thresh=args.energy_thresh, energy_upper_limit=args.energy_upper_limit, extra_constraints=constraints_dict, verbose=args.verbose)
    # Run the scan!
    scanner.master()
    # After finish, print result
    print("Dihedral scan is finished!")
    print(" Grid ID                Energy")
    for grid_id in sorted(scanner.grid_energies.keys()):
        print("  %-20s %.10f" % (str(grid_id), scanner.grid_energies[grid_id]))
Beispiel #5
0
def test_dihedral_scanner_methods():
    """
    Testing methods of DihedralScanner
    """
    # setup a scanner
    m = Molecule()
    m.elem = ['H'] * 5
    m.xyzs = [
        np.array([[0, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 1], [1, 0, 0]],
                 dtype=float) * 0.5
    ]
    m.build_topology()
    engine = EngineBlank()
    dihedrals = [[0, 1, 2, 3], [1, 2, 3, 4]]
    scanner = DihedralScanner(engine,
                              dihedrals=dihedrals,
                              grid_spacing=[30, 30],
                              init_coords_M=m)
    # test methods
    gid = (120, -60)
    assert scanner.get_dihedral_id(m) == gid
    assert scanner.get_dihedral_id(m, check_grid_id=(120, -90)) == None
    assert set(scanner.grid_neighbors(gid)) == {(90, -60), (150, -60),
                                                (120, -90), (120, -30)}
    assert set(scanner.grid_full_neighbors(gid)) == {(90, -90), (90, -30),
                                                     (150, -90), (150, -30)}
    scanner.push_initial_opt_tasks()
    assert len(scanner.opt_queue) == 1
    geo, start_gid, end_gid = scanner.opt_queue.pop()
    assert start_gid == end_gid
def test_dihedral_scanner_setup():
    """
    Testing DihedralScanner Setup for 1-D to 4-D Scans
    """
    engine = EngineBlank()
    for dim in range(1, 5):
        print("Testing %d-D scan setup" % dim)
        dihedrals = [list(range(d, d+4)) for d in range(dim)]
        scanner = DihedralScanner(engine, dihedrals=dihedrals, grid_spacing=[90]*dim)
        gid = scanner.grid_ids[0]
        assert len(scanner.grid_ids) == 4**dim and len(gid) == dim, "Wrong dimension of grid_ids"
        assert len(scanner.grid_neighbors(gid)) == 2*dim, "Wrong dimension of grid_neighbors"
        assert isinstance(scanner.opt_queue, PriorityQueue), "DihedralScanner.opt_queue should be an instance of PriorityQueue"
        assert len(scanner.opt_queue) == 0, "DihedralScanner.opt_queue should be empty after setup"
def test_reproduce_1D_examples(example_path):
    """
    Testing Reproducing examples/hooh-1d
    """
    from torsiondrive import launch
    # reproduce psi4 local geomeTRIC
    os.chdir(example_path)
    os.chdir('hooh-1d/psi4/run_local/geomeTRIC')
    subprocess.run('tar zxf opt_tmp.tar.gz', shell=True, check=True)
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs, dihedral_ranges = launch.load_dihedralfile('dihedrals.txt')
    engine = launch.create_engine('psi4', inputfile='input.dat')
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
    # reproduce psi4 local native_opt
    os.chdir(example_path)
    os.chdir('hooh-1d/psi4/run_local/native_opt')
    subprocess.run('tar zxf opt_tmp.tar.gz', shell=True, check=True)
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs, dihedral_ranges = launch.load_dihedralfile('dihedrals.txt')
    engine = launch.create_engine('psi4',
                                  inputfile='input.dat',
                                  native_opt=True)
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
    # reproduce qchem local geomeTRIC
    os.chdir(example_path)
    os.chdir('hooh-1d/qchem/run_local/geomeTRIC')
    subprocess.run('tar zxf opt_tmp.tar.gz', shell=True, check=True)
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs, dihedral_ranges = launch.load_dihedralfile('dihedrals.txt')
    engine = launch.create_engine('qchem', inputfile='qc.in')
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
    # reproduce Gaussian local native_opt
    os.chdir(example_path)
    os.chdir('hooh-1d/gaussian/run_local/native_opt')
    subprocess.run('tar zxf opt_tmp.tar.gz', shell=True, check=True)
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs, dihedral_ranges = launch.load_dihedralfile('dihedrals.txt')
    engine = EngineGaussian(input_file="input.com", native_opt=True, exe="g09")
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
    # reproduce Gaussian local geometric
    os.chdir(example_path)
    os.chdir('hooh-1d/gaussian/run_local/geomeTRIC')
    subprocess.run('tar zxf opt_tmp.tar.gz', shell=True, check=True)
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs, dihedral_ranges = launch.load_dihedralfile('dihedrals.txt')
    engine = EngineGaussian(input_file="input.com",
                            native_opt=False,
                            exe="g09")
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
    # reproduce qchem local native_opt (skipped because qchem failed in this example)
    # os.chdir(example_path)
    # os.chdir('hooh-1d/qchem/run_local/native_opt')
    # subprocess.run('tar zxf opt_tmp.tar.gz', shell=True, check=True)
    # shutil.copy('scan.xyz', 'orig_scan.xyz')
    # dihedral_idxs, dihedral_ranges = launch.load_dihedralfile('dihedrals.txt')
    # engine = launch.create_engine('qchem', inputfile='input.dat', native_opt=True)
    # scanner = DihedralScanner(engine, dihedrals=dihedral_idxs, grid_spacing=[15], verbose=True)
    # scanner.master()
    # assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
    # reproduce terachem local geomeTRIC
    os.chdir(example_path)
    os.chdir('hooh-1d/terachem/run_local/geomeTRIC')
    subprocess.run('tar zxf opt_tmp.tar.gz', shell=True, check=True)
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs, dihedral_ranges = launch.load_dihedralfile('dihedrals.txt')
    engine = launch.create_engine('terachem', inputfile='run.in')
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
    # reproduce terachem local native_opt
    os.chdir(example_path)
    os.chdir('hooh-1d/terachem/run_local/native_opt')
    subprocess.run('tar zxf opt_tmp.tar.gz', shell=True, check=True)
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs, dihedral_ranges = launch.load_dihedralfile('dihedrals.txt')
    engine = launch.create_engine('terachem',
                                  inputfile='run.in',
                                  native_opt=True)
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
    # reproduce openmm local geomeTRIC
    os.chdir(example_path)
    os.chdir('hooh-1d/openmm/run_local/geometric')
    subprocess.run('tar zxf opt_tmp.tar.gz', shell=True, check=True)
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs, dihedral_ranges = launch.load_dihedralfile('dihedrals.txt')
    engine = launch.create_engine('openmm', inputfile='hooh.pdb')
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
Beispiel #8
0
def test_reproduce_1D_examples():
    """
    Testing Reproducing examples/hooh-1d
    """
    from torsiondrive import launch
    this_file_folder = os.path.dirname(os.path.realpath(__file__))
    example_path = os.path.join(this_file_folder, '..', '..', 'examples')
    os.chdir(example_path)
    subprocess.call('tar zxf hooh-1d.tar.gz ', shell=True)
    # reproduce psi4 local geomeTRIC
    os.chdir('hooh-1d/psi4/run_local/geomeTRIC')
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs = launch.load_dihedralfile('dihedrals.txt',
                                             zero_based_numbering=True)
    engine = launch.create_engine('psi4', inputfile='input.dat')
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
    os.chdir(example_path)
    # reproduce psi4 local native_opt
    os.chdir('hooh-1d/psi4/run_local/native_opt')
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs = launch.load_dihedralfile('dihedrals.txt',
                                             zero_based_numbering=True)
    engine = launch.create_engine('psi4',
                                  inputfile='input.dat',
                                  native_opt=True)
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
    os.chdir(example_path)
    # reproduce qchem local geomeTRIC
    os.chdir('hooh-1d/qchem/run_local/geomeTRIC')
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs = launch.load_dihedralfile('dihedrals.txt',
                                             zero_based_numbering=True)
    engine = launch.create_engine('qchem', inputfile='qc.in')
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
    os.chdir(example_path)
    # reproduce terachem local geomeTRIC
    os.chdir('hooh-1d/terachem/run_local/geomeTRIC')
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs = launch.load_dihedralfile('dihedrals.txt',
                                             zero_based_numbering=True)
    engine = launch.create_engine('terachem', inputfile='run.in')
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
Beispiel #9
0
def test_reproduce_1D_examples(example_path):
    """
    Testing Reproducing examples/hooh-1d
    """
    from torsiondrive import launch
    # reproduce psi4 local geomeTRIC
    os.chdir(example_path)
    os.chdir('hooh-1d/psi4/run_local/geomeTRIC')
    subprocess.run('tar zxf opt_tmp.tar.gz', shell=True, check=True)
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs, dihedral_ranges = launch.load_dihedralfile('dihedrals.txt')
    engine = launch.create_engine('psi4', inputfile='input.dat')
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
    # reproduce psi4 local native_opt
    os.chdir(example_path)
    os.chdir('hooh-1d/psi4/run_local/native_opt')
    subprocess.run('tar zxf opt_tmp.tar.gz', shell=True, check=True)
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs, dihedral_ranges = launch.load_dihedralfile('dihedrals.txt')
    engine = launch.create_engine('psi4',
                                  inputfile='input.dat',
                                  native_opt=True)
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
    # reproduce qchem local geomeTRIC
    os.chdir(example_path)
    os.chdir('hooh-1d/qchem/run_local/geomeTRIC')
    subprocess.run('tar zxf opt_tmp.tar.gz', shell=True, check=True)
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs, dihedral_ranges = launch.load_dihedralfile('dihedrals.txt')
    engine = launch.create_engine('qchem', inputfile='qc.in')
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')
    # reproduce terachem local geomeTRIC
    os.chdir(example_path)
    os.chdir('hooh-1d/terachem/run_local/geomeTRIC')
    subprocess.run('tar zxf opt_tmp.tar.gz', shell=True, check=True)
    shutil.copy('scan.xyz', 'orig_scan.xyz')
    dihedral_idxs, dihedral_ranges = launch.load_dihedralfile('dihedrals.txt')
    engine = launch.create_engine('terachem', inputfile='run.in')
    scanner = DihedralScanner(engine,
                              dihedrals=dihedral_idxs,
                              grid_spacing=[15],
                              verbose=True)
    scanner.master()
    assert filecmp.cmp('scan.xyz', 'orig_scan.xyz')