예제 #1
0
    def test_chunks(self):

        full_len = 10
        chunk_len = 3
        chunk_n = 2

        # Generate a few random structures
        elrnd = ['H', 'C', 'O', 'N']
        asernd = []
        for n in range(full_len):
            aselen = np.random.randint(1, 10)
            asernd.append(
                Atoms(symbols=np.random.choice(elrnd, aselen),
                      positions=np.random.random((aselen, 3))))

        testcoll = AtomsCollection(asernd)

        # Test with size
        chunks = testcoll.chunkify(chunk_size=chunk_len)
        self.assertEqual(len(chunks), np.ceil(full_len / (1.0 * chunk_len)))
        self.assertEqual(chunks[-1].length, full_len % chunk_len)

        # Test with number
        chunks = testcoll.chunkify(chunk_n=chunk_n)
        self.assertEqual(len(chunks), chunk_n)
예제 #2
0
    def test_loadarray(self):

        g0 = Gene('latt_abc_len', 1.0, {})

        c1 = AtomsCollection([Atoms('C'), Atoms('C')])
        c1.set_array('latt_abc_len', [1, 2])
        p1 = PhylogenCluster(c1, [])

        p1.set_genes([g0], load_arrays=True)

        self.assertTrue(np.all(p1.get_genome_vectors()[0] == [[1], [2]]))
예제 #3
0
    def test_loadres(self):

        # Load some test files and check if regular loading works
        reslist = glob.glob(
            os.path.join(_TESTDATA_DIR, 'rescollection', '*.res'))
        testcoll = AtomsCollection(reslist)
        self.assertEqual(testcoll.length, len(reslist))

        # Now try the same, but with single atoms objects
        aselist = [io.read(str(fname)) for fname in reslist]
        testcoll = AtomsCollection(aselist)
        self.assertEqual(testcoll.length, len(reslist))
예제 #4
0
    def test_tree(self):

        aselist = [Atoms('C'), Atoms('H'), Atoms('N'), Atoms('O')]

        testcoll = AtomsCollection(aselist)

        testcoll.save_tree('test_save', 'xyz', safety_check=2)
        loadcoll = AtomsCollection.load_tree('test_save', 'xyz')

        self.assertTrue(''.join(loadcoll.all.get_chemical_formula()) == 'CHNO')

        # Try a custom save format
        def custom_save(a, path, format_string):
            with open(os.path.join(path, 'struct.custom'), 'w') as f:
                f.write(format_string.format(''.join(
                    a.get_chemical_formula())))

        def custom_load(path, marker):
            with open(os.path.join(path, 'struct.custom')) as f:
                l = f.read().strip()
                return Atoms(l.split(marker)[1].strip())

        testcoll.save_tree('test_save',
                           custom_save,
                           opt_args={'format_string': 'Formula:{0}'},
                           safety_check=2)
        loadcoll = AtomsCollection.load_tree('test_save',
                                             custom_load,
                                             opt_args={'marker': ':'})

        self.assertTrue(''.join(loadcoll.all.get_chemical_formula()) == 'CHNO')
예제 #5
0
    def test_airss(self):

        to_gen = 10

        # Load the Al.cell file (capture the annoying ASE output...)
        _stdout, sys.stdout = sys.stdout, StringIO()
        agen = airssGen(os.path.join(_TESTDATA_DIR, 'Al.cell'), n=to_gen)

        try:
            acoll = AtomsCollection(agen)
        except RuntimeError as e:
            if 'Buildcell' in str(e):
                sys.stdout = _stdout
                # Then we just don't have the program
                print('WARNING - The AIRSS generator could not be tested as '
                      'no AIRSS installation has been found on this system.')
                return
            else:
                raise e

        sys.stdout = _stdout

        # Some basic checks
        self.assertEqual(acoll.length, to_gen)
        self.assertTrue(
            all([chem == 'Al8' for chem in acoll.all.get_chemical_formula()]))
예제 #6
0
def load_muairss_collection(struct, params, batch_path=''):

    # Output folder
    out_path = os.path.join(batch_path, params['out_folder'])

    load_formats = {
        'dftb+': dftb_read_input,
        'castep': castep_read_input,
        'uep': uep_read_input
    }

    calcs = [s.strip().lower() for s in params['calculator'].split(',')]
    if 'all' in calcs:
        calcs = load_formats.keys()

    loaded = {}


    for cname in calcs:
        opt_args = {}
        if cname == 'uep':
            opt_args['atoms'] = struct

        calc_path = os.path.join(out_path, cname)
        dc = AtomsCollection.load_tree(calc_path, load_formats[cname],
                                       opt_args=opt_args, safety_check=2)
        loaded[cname] = dc

    return loaded
예제 #7
0
    def test_cluster(self):

        a1 = Atoms(cell=[1, 1, 1], info={'name': 'a1'})
        a2 = Atoms(cell=[1, 1, 2], info={'name': 'a2'})
        a3 = Atoms(cell=[3, 3, 3], info={'name': 'a3'})

        c1 = AtomsCollection([a1, a2, a3])
        p1 = PhylogenCluster(c1, [Gene('latt_abc_len', 1.0, {})])

        clinds, clslice = p1.get_hier_clusters(0.5, method='complete')

        getname = lambda a: a.info['name']

        cnames = [sorted(c1[sl].all.map(getname)) for sl in clslice]
        cnames.sort(key=lambda x: len(x))

        self.assertTrue(cnames == [['a3'], ['a1', 'a2']])

        # Retry with k-means

        clustc = p1.get_kmeans_clusters(2)

        cnames = [sorted(c1[sl].all.map(getname)) for sl in clslice]
        cnames.sort(key=lambda x: len(x))

        self.assertTrue(cnames == [['a3'], ['a1', 'a2']])
예제 #8
0
    def test_diprotavg(self):
        # Test dipolar rotational averaging

        eth = io.read(os.path.join(_TESTDATA_DIR, 'ethanol.magres'))

        from ase.quaternions import Quaternion
        from soprano.properties.transform import Rotate
        from soprano.collection import AtomsCollection
        from soprano.collection.generate import transformGen
        from soprano.properties.nmr import DipolarTensor

        N = 30  # Number of averaging steps
        axis = np.array([1.0, 1.0, 0])
        axis /= np.linalg.norm(axis)

        rot = Rotate(quaternion=Quaternion.from_axis_angle(
            axis, 2*np.pi/N))

        rot_eth = AtomsCollection(transformGen(eth, rot, N))

        rot_dip = [D[(0, 1)]
                   for D in DipolarTensor.get(rot_eth, sel_i=[0], sel_j=[1])]

        dip_avg_num = np.average(rot_dip, axis=0)

        dip_tens = NMRTensor.make_dipolar(eth, 0, 1, rotation_axis=axis)
        dip_avg_tens = dip_tens.data

        self.assertTrue(np.allclose(dip_avg_num, dip_avg_tens))

        # Test eigenvectors
        evecs = dip_tens.eigenvectors
        self.assertTrue(np.allclose(np.dot(evecs.T, evecs), np.eye(3)))
예제 #9
0
def generate_muairss_collection(struct, params):

    if params["mu_symbol"] in struct.get_chemical_symbols():
        print(
            "WARNING: chosen muon symbol conflicts with existing elements in"
            " the starting unit cell. This could cause mistakes"
        )

    # Make a supercell
    sm = make_3x3(params["supercell"])
    # ASE's make_supercell is weird, avoid if not necessary...
    smdiag = np.diag(sm).astype(int)
    if np.all(np.diag(smdiag) == sm):
        scell0 = struct.repeat(smdiag)
    else:
        scell0 = make_supercell(struct, sm)

    reduced_struct = find_primitive_structure(struct)

    print("Generating defect configurations...")
    # Seed the random generator
    Random.reseed(params["random_seed"])
    # Now generate the defect configurations
    defect_gen = defectGen(
        reduced_struct,
        "H",
        poisson_r=params["poisson_r"],
        vdw_scale=params["vdw_scale"],
    )
    defect_collection = AtomsCollection(defect_gen)
    print("{0} configurations generated".format(len(defect_collection)))

    collection = []
    for atoms in defect_collection:
        # Where's the muon?
        # We rely on the fact that it's always put at the first place
        mupos = atoms.get_positions()[0]
        scell = scell0.copy() + Atoms(
            "H", positions=[mupos], masses=[constants.m_mu_amu]
        )
        # Add castep custom species
        csp = scell0.get_chemical_symbols() + [params["mu_symbol"]]
        scell.set_array("castep_custom_species", np.array(csp))
        scell.set_pbc(params["dftb_pbc"])
        collection.append(scell)

    return AtomsCollection(collection)
예제 #10
0
    def test_propertymap(self):

        from soprano.properties.basic import NumAtoms

        num_atoms = np.random.randint(1, 11, size=10)
        coll = AtomsCollection([Atoms('H'*n) for n in num_atoms])

        num_atoms_prop = coll.all.map(NumAtoms.get)

        self.assertTrue((num_atoms == num_atoms_prop).all)
예제 #11
0
    def test_linspace(self):

        a1 = Atoms('CO', [[0.0, 0.0, 0.0], [0.0, 0.2, 0.0]], cell=[1] * 3)
        a2 = Atoms('CO', [[0.0, 0.0, 0.0], [0.0, 0.8, 0.0]], cell=[1] * 3)

        lgen = linspaceGen(a1, a2, steps=5, periodic=False)
        lcoll = AtomsCollection(lgen)

        self.assertTrue(
            np.all(
                np.isclose(lcoll.all.get_positions()[:, 1, 1],
                           np.linspace(0.2, 0.8, 5))))

        # With periodicity
        lgen = linspaceGen(a1, a2, steps=5, periodic=True)
        lcoll = AtomsCollection(lgen)

        self.assertTrue(
            np.all(
                np.isclose(lcoll.all.get_positions()[:, 1, 1],
                           np.linspace(0.2, -0.2, 5))))
예제 #12
0
    def test_mapsel(self):

        from soprano.collection import AtomsCollection

        rand_el = ['H' if x > 0.5 else 'C' for x in np.random.random(10)]
        coll = AtomsCollection([Atoms(el) for el in rand_el])

        h_sel = coll.all.map(AtomSelection.from_element, element='H')

        self.assertTrue(all([len(s) == 1 if rand_el[i] == 'H'
                             else len(s) == 0
                             for i, s in enumerate(h_sel)]))
예제 #13
0
    def test_gene(self):

        c1 = AtomsCollection([
            Atoms('CCC',
                  positions=[[0, 0, 0], [0.2, 0, 0], [0.85, 0, 0]],
                  cell=[1] * 3)
        ])
        g1 = Gene('linkage_list', 1.0, {'size': 3})
        p1 = PhylogenCluster(c1, [g1])

        graw = p1.get_genome_vectors()
        self.assertTrue(np.allclose(graw[0], [0.15, 0.2, 0.35]))
예제 #14
0
    def test_save(self):

        # Test saving and loading collection
        testcoll = AtomsCollection([Atoms('H')])
        testcoll.set_array('test', np.array([2]))

        outf = os.path.join(_TEST_DIR, 'collection.pkl')
        testcoll.save(outf)

        # Reload
        testcoll = AtomsCollection.load(outf)
        self.assertEqual(testcoll.get_array('test')[0], 2)

        os.remove(outf)
예제 #15
0
    def test_calculator(self):

        from ase.calculators.test import TestPotential
        from ase.calculators.lj import LennardJones

        # Generate a few random structures
        elrnd = ['H', 'C', 'O', 'N']
        asernd = []
        for n in range(4):
            aselen = np.random.randint(2, 10)
            asernd.append(
                Atoms(symbols=np.random.choice(elrnd, aselen),
                      positions=np.random.random((aselen, 3))))

        testcoll = AtomsCollection(asernd)

        testcoll.set_calculators(LennardJones,
                                 labels=['a', 'b', 'c', 'd'],
                                 params={'epsilon': 1.2})
        testcoll.run_calculators()

        def extract_nrg(s):
            return s.calc.results['energy']

        energies = np.array(testcoll.all.map(extract_nrg))

        self.assertTrue(not np.isnan(energies).any())
예제 #16
0
    def test_dummyprop(self):

        # Define a dummy derived property and test it

        class DummyProperty(AtomsProperty):

            default_name = 'dummy'
            default_params = {'mul': 2.0}

            @staticmethod
            def extract(s, mul):
                return s.positions.shape[0] * mul

        # Now two atoms objects to test it on
        a1 = Atoms('C')
        a2 = Atoms('CC')

        dummyDoubled = DummyProperty(name='doubledummy', mul=4)

        self.assertEqual(DummyProperty.get(a1), 2.0)
        self.assertEqual(dummyDoubled(a2), 8.0)

        # Also check that improper parameters are rejected
        self.assertRaises(ValueError, DummyProperty, wrong='this is wrong')

        # Test behaviour on a collection instead
        c1 = AtomsCollection([a1, a2])
        c2 = AtomsCollection([a2, a1])

        DummyProperty.get(c1, store_array=True)
        dummyDoubled(c2, store_array=True)
        self.assertTrue(np.all(c1.get_array('dummy') == [2, 4]))
        self.assertTrue(np.all(c2.get_array('doubledummy') == [8, 4]))
예제 #17
0
    def test_slices(self):

        aselist = [Atoms('C'), Atoms('C'), Atoms('H'), Atoms('C')]

        testcoll = AtomsCollection(aselist)

        coll_h = testcoll[2]
        coll_c = testcoll[(0, 1, 3)]

        self.assertTrue(
            all([f == 'H' for f in coll_h.all.get_chemical_formula()]))
        self.assertTrue(
            all([f == 'C' for f in coll_c.all.get_chemical_formula()]))
예제 #18
0
def generate_muairss_collection(struct, params):

    if params['mu_symbol'] in struct.get_chemical_symbols():
        print('WARNING: chosen muon symbol conflicts with existing elements in'
              ' the starting unit cell. This could cause mistakes')

    # Make a supercell
    sm = make_3x3(params['supercell'])
    # ASE's make_supercell is weird, avoid if not necessary...
    smdiag = np.diag(sm).astype(int)
    if np.all(np.diag(smdiag) == sm):
        scell0 = struct.repeat(smdiag)
    else:
        scell0 = make_supercell(struct, sm)

    reduced_struct = find_primitive_structure(struct)

    print('Generating defect configurations...')
    # Now generate the defect configurations
    defect_gen = defectGen(reduced_struct,
                           'H',
                           poisson_r=params['poisson_r'],
                           vdw_scale=params['vdw_scale'])
    defect_collection = AtomsCollection(defect_gen)
    print('{0} configurations generated'.format(len(defect_collection)))

    collection = []
    for atoms in defect_collection:
        # Where's the muon?
        # We rely on the fact that it's always put at the first place
        mupos = atoms.get_positions()[0]
        scell = scell0.copy() + Atoms('H', positions=[mupos])
        # Add castep custom species
        csp = scell0.get_chemical_symbols() + [params['mu_symbol']]
        scell.set_array('castep_custom_species', np.array(csp))
        scell.set_pbc(params['dftb_pbc'])
        collection.append(scell)

    return AtomsCollection(collection)
예제 #19
0
    def test_customgene(self):

        c1 = AtomsCollection(
            [Atoms('C', positions=[[i / 5.0, 0, 0]]) for i in range(5)])

        # First, check failure
        self.assertRaises(RuntimeError, Gene, 'first_x_coord')

        # Then actual success
        def first_x_parser(c):
            return np.array(c.all.get_positions())[:, 0, 0]

        g1 = Gene('first_x_coord', parser=first_x_parser)
        self.assertTrue(np.all(g1.evaluate(c1) == [i / 5.0 for i in range(5)]))
예제 #20
0
    def test_loadgene(self):

        gfpath = os.path.join(_TESTDATA_DIR, 'testfile.gene')

        g0 = Gene('latt_abc_len', 1.0, {})
        g1 = Gene('linkage_list', 0.5, {'size': 3})
        glist = load_genefile(gfpath)

        self.assertEqual(glist[0], g0)
        self.assertEqual(glist[1], g1)

        # Now test that it works also when instantiating a cluster
        c1 = AtomsCollection(
            [Atoms('CCC', positions=np.random.random((3, 3)), cell=[1] * 3)])
        p1 = PhylogenCluster(c1, gfpath)
예제 #21
0
    def test_arrays(self):

        # Generate a few random structures
        elrnd = ['H', 'C', 'O', 'N']
        asernd = []
        for n in range(4):
            aselen = np.random.randint(1, 10)
            asernd.append(
                Atoms(symbols=np.random.choice(elrnd, aselen),
                      positions=np.random.random((aselen, 3))))

        testcoll = AtomsCollection(asernd)
        # Now try assigning some arrays
        arr = np.arange(testcoll.length)
        testcoll.set_array('testarr', arr, shape=(1, ))
        testcoll.set_array('testarr_2', list(zip(arr, arr)), shape=(2, ))
        testcoll.set_array('testarr_func',
                           lambda a: len(a.get_positions()),
                           shape=(1, ))

        self.assertTrue(np.all(testcoll.get_array('testarr') == arr))
예제 #22
0
    def test_rattle(self):

        a = Atoms('CO', [[0.0, 0.0, 0.0], [0.0, 0.5, 0.0]])
        pos = a.get_positions()

        # Some exception tests
        wronggen = rattleGen(a, [3, 4, 5])
        self.assertRaises(ValueError, next, wronggen)
        wronggen = rattleGen(a, [[1, 2], [4, 5]])
        self.assertRaises(ValueError, next, wronggen)

        rgen = rattleGen(a, [[0.01, 0, 0], [0, 0.02, 0]])
        rcoll = AtomsCollection(rgen)
        rpos = rcoll.all.get_positions()

        self.assertTrue(np.all(np.abs((rpos - pos)[:, 0, 0]) <= 0.01))
        self.assertTrue(np.all(np.abs((rpos - pos)[:, 1, 1]) <= 0.02))
예제 #23
0
    def test_defect(self):

        si2 = bulk('Si')

        poisson_r = 0.5

        dGen = defectGen(si2, 'H', poisson_r)
        dColl = AtomsCollection(dGen)

        dPos = dColl.all.get_positions()[:, 0]

        holds = True
        for i, p1 in enumerate(dPos[:-1]):
            vecs, _ = minimum_periodic(dPos[i + 1:] - p1, si2.get_cell())
            p_holds = (np.linalg.norm(vecs, axis=1) >= poisson_r).all()
            holds = holds and p_holds

        self.assertTrue(holds)
예제 #24
0
    def test_coordhist(self):

        ala = ase.io.read(os.path.join(_TESTDATA_DIR, 'mol_crystal.cif'))
        nh3 = ase.io.read(os.path.join(_TESTDATA_DIR, 'nh3.cif'))

        c = AtomsCollection([ala, nh3])

        g = Gene('coord_histogram')
        h = g.evaluate(c)

        self.assertTrue((h[0] == [0, 4, 0, 4, 0, 0, 0]).all())
        self.assertTrue((h[1] == 0).all())  # No C at all in this one

        # Now for something different...
        g = Gene('coord_histogram', params={'s1': 'N'})
        h = g.evaluate(c)

        self.assertTrue((h[0] == [0, 0, 0, 4, 0, 0, 0]).all())  # 4 NH3 groups
        self.assertTrue((h[1] == [0, 0, 0, 1, 0, 0, 0]).all())
예제 #25
0
    def test_sum(self):

        # Generate a few random structures
        elrnd = ['H', 'C', 'O', 'N']
        asernd = []
        for n in range(4):
            aselen = np.random.randint(1, 10)
            asernd.append(
                Atoms(symbols=np.random.choice(elrnd, aselen),
                      positions=np.random.random((aselen, 3))))

        testcoll1 = AtomsCollection(asernd[:2])
        testcoll2 = AtomsCollection(asernd[2:])

        testcoll1.set_array('joint', ['t', 'e'])
        testcoll2.set_array('joint', ['s', 't'])

        testcoll = testcoll1
        testcoll += testcoll2

        self.assertTrue(''.join(testcoll.get_array('joint')) == 'test')
예제 #26
0
def load_muairss_collection(struct, params, batch_path=""):

    # Output folder
    out_path = os.path.join(batch_path, params["out_folder"])

    io_formats = {
        "castep": ReadWriteCastep,
        "dftb+": ReadWriteDFTB,
        "uep": ReadWriteUEP,
    }

    calcs = [s.strip().lower() for s in params["calculator"].split(",")]
    if "all" in calcs:
        calcs = io_formats.keys()

    loaded = {}

    for cname in calcs:
        rw = io_formats[cname](params)
        calc_path = os.path.join(out_path, cname)

        dc = AtomsCollection.load_tree(
            calc_path, rw.read, safety_check=2, tolerant=True
        )

        alln = len(glob.glob(calc_path + "/*"))

        total_structures = len(dc.structures)
        if total_structures == 0:
            return
        elif total_structures / alln < 0.9:
            print(
                """If more than 10% of structures could not be loaded,
we advise adjusting the parameters and re-running the {0}
optimisation for the structures that failed.""".format(
                    cname
                )
            )

        loaded[cname] = dc

    return loaded
예제 #27
0
    def test_sorting(self):

        # Generate a few structures
        struct_n = 5

        aselist = []
        for n in range(struct_n):
            aselist.append(Atoms())

        testcoll = AtomsCollection(aselist)

        testcoll.set_array('sorter', np.array(range(struct_n, 0, -1)))
        testcoll.set_array('sorted', np.array(range(1, struct_n + 1)))

        testcoll = testcoll.sorted_byarray('sorter')

        self.assertTrue(
            np.all(testcoll.get_array('sorted') == range(struct_n, 0, -1)))
예제 #28
0
def load_muairss_collection(struct, params, batch_path=''):

    # Output folder
    out_path = os.path.join(batch_path, params['out_folder'])

    io_formats = {
        'castep': ReadWriteCastep,
        'dftb+': ReadWriteDFTB,
        'uep': ReadWriteUEP
    }

    calcs = [s.strip().lower() for s in params['calculator'].split(',')]
    if 'all' in calcs:
        calcs = io_formats.keys()

    loaded = {}

    for cname in calcs:
        rw = io_formats[cname](params)
        calc_path = os.path.join(out_path, cname)

        dc = AtomsCollection.load_tree(calc_path,
                                       rw.read,
                                       safety_check=2,
                                       tolerant=True)

        print("If more than 10% of structures could not be loaded, \
we advise adjusting the parameters and re-running the {0} \
optimisation for the structures that failed.".format(cname))

        total_structures = len(dc.structures)
        if total_structures == 0:
            return

        loaded[cname] = dc

    return loaded
예제 #29
0
def muon_vibrational_average_write(structure,
                                   method="independent",
                                   mu_index=-1,
                                   mu_symbol="H:mu",
                                   grid_n=20,
                                   sigma_n=3,
                                   avgprop="hyperfine",
                                   calculator="castep",
                                   displace_T=0,
                                   phonon_source_file=None,
                                   phonon_source_type="castep",
                                   **kwargs):
    """
    Write input files to compute a vibrational average for a quantity on a muon
    in a given system.

    | Pars:
    |   structure (str):    Filename for input structure file
    |   method (str):       Method to use for the average. Options are
    |                       'independent', 'montecarlo'.
    |                       Default is 'independent'.
    |   mu_index (int):     Position of the muon in the given cell file.
    |                       Default is -1.
    |   mu_symbol (str):    Use this symbol to look for the muon among
    |                       CASTEP custom species. Overrides muon_index if
    |                       present in cell.
    |   grid_n (int):       Number of configurations used for sampling.
    |                       Applies slightly
    |                       differently to different schemes.
    |   sigma_n (int):      Number of sigmas of the harmonic wavefunction used
    |                       for sampling.
    |   avgprop (str):      Property to calculate and average. Default is
    |                       'hyperfine'.
    |   calculator (str):   Source of the property to calculate and average.
    |                       Can be 'castep' or 'dftb+'. Default is 'castep'.
    |   phonon_source (str):Source of the phonon data. Can be 'castep' or
    |                       'asedftbp'. Default is 'castep'.
    |   **kwargs:           Other arguments (such as specific arguments for
    |                       the given phonon method)
    """

    # Open the structure file
    with silence_stdio():
        cell = io.read(structure)
    path = os.path.split(structure)[0]
    sname = seedname(structure)

    cell.info["name"] = sname

    # Fetch species
    try:
        species = cell.get_array("castep_custom_species")
    except KeyError:
        species = np.array(cell.get_chemical_symbols())

    mu_indices = np.where(species == mu_symbol)[0]
    if len(mu_indices) > 1:
        raise MuonAverageError("More than one muon found in the system")
    elif len(mu_indices) == 1:
        mu_index = mu_indices[0]
    else:
        species = list(species)
        species[mu_index] = mu_symbol
        species = np.array(species)

    cell.set_array("castep_custom_species", species)

    io_formats = {"castep": ReadWriteCastep, "dftb+": ReadWriteDFTB}

    # Load the phonons
    if phonon_source_file is not None:
        phpath, phfile = os.path.split(phonon_source_file)
        phfile = seedname(seedname(phfile))  # have to do twice for dftb case
    else:
        phpath = path
        phfile = sname

    try:
        rw = io_formats[phonon_source_type]()
        atoms = rw.read(phpath, phfile, read_phonons=True)
        ph_evals = atoms.info["ph_evals"]
        ph_evecs = atoms.info["ph_evecs"]
    except IOError:
        raise
        return
    except KeyError:
        phonon_source_file = os.path.join(phpath, phfile + ".phonon")
        if phonon_source_type == "dftb+":
            phonon_source_file = phonon_source_file + "s.pkl"
        raise (IOError(
            "Phonon file {0} could not be read.".format(phonon_source_file)))
        return

    # Fetch masses
    try:
        masses = parse_castep_masses(cell)
    except AttributeError:
        # Just fall back on ASE standard masses if not available
        masses = cell.get_masses()
    masses[mu_index] = constants.m_mu_amu
    cell.set_masses(masses)

    # Now create the distribution scheme
    if method == "independent":
        displsch = IndependentDisplacements(ph_evals, ph_evecs, masses,
                                            mu_index, sigma_n)
    elif method == "montecarlo":
        # Set seed
        np.random.seed(kwargs["random_seed"])
        displsch = MonteCarloDisplacements(ph_evals, ph_evecs, masses)

    displsch.recalc_displacements(n=grid_n, T=displace_T)

    # Make it a collection
    pos = cell.get_positions()
    displaced_cells = []
    for i, d in enumerate(displsch.displacements):
        dcell = cell.copy()
        dcell.set_positions(pos + d)
        if calculator == "dftb" and not kwargs["dftb_pbc"]:
            dcell.set_pbc(False)
        dcell.info["name"] = sname + "_displaced_{0}".format(i)
        displaced_cells.append(dcell)

    if kwargs["write_allconf"]:
        # Write a global configuration structure
        allconf = sum(displaced_cells, cell.copy())
        with silence_stdio():
            if all(allconf.get_pbc()):
                io.write(sname + "_allconf.cell", allconf)
            else:
                io.write(sname + "_allconf.xyz", allconf)

    # Get a calculator
    if calculator == "castep":
        params = {
            "castep_param": kwargs["castep_param"],
            "k_points_grid": kwargs["k_points_grid"],
            "mu_symbol": mu_symbol,
        }
        io_format = ReadWriteCastep(params=params,
                                    calc=cell.calc,
                                    script=kwargs["script_file"])
        opt_args = {"calc_type": "MAGRES"}

    elif calculator == "dftb+":
        params = {
            "dftb_set":
            kwargs["dftb_set"],
            "dftb_pbc":
            kwargs["dftb_pbc"],
            "k_points_grid":
            kwargs["k_points_grid"] if kwargs["dftb_pbc"] else None,
        }
        io_format = ReadWriteDFTB(params=params,
                                  calc=cell.calc,
                                  script=kwargs["script_file"])
        opt_args = {"calc_type": "SPINPOL"}

    displaced_coll = AtomsCollection(displaced_cells)
    displaced_coll.info["displacement_scheme"] = displsch
    displaced_coll.info["muon_index"] = mu_index
    displaced_coll.save_tree(sname + "_displaced",
                             io_format.write,
                             opt_args=opt_args)
예제 #30
0
parser.add_argument('-corrmat_minforce',     type=float, default=0.01,
                    help="Correlation matrix minimum force")
parser.add_argument('-corrmat_maxforce',     type=float, default=1.0,
                    help="Correlation matrix maximum force")
parser.add_argument('-savepkl',  type=str, default=None,
                    help="Directory to save collection as pickle file")

args = parser.parse_args()

# First, parse the gene list
gene_list = load_genefile(args.seedname + '.gene')

# Then create an AtomsCollection
if not args.pkl:
    aC = AtomsCollection(args.input_files,
                         info={'name': args.seedname},
                         cell_reduce=True,
                         progress=True)
else:
    aC = AtomsCollection([])
    for f in args.input_files:
        aC += AtomsCollection.load(f)

# Take only n lowest energies if required
if (args.n is not None):
    # Sort by energy
    CalcEnergy.get(aC, store_array=True)
    aC = aC.sorted_byarray('calc_energy')[:args.n]

#discard_Z = args.Z is not None

# Calculate genomes