def check_generated(calc_root, machine_dct, params_lst, revision): """Check consistency of calc database values, replacement params in `params_lst` and all written files. """ dbfn = pj(calc_root, 'calc.db') db = sql.SQLiteDB(dbfn, table='calc') print("database content:") print(db.get_dict("select * from calc")) db_colnames = [x[0] for x in db.get_header()] for idx, hostname_str in db.execute( "select idx,hostname from calc \ where revision==?", (revision, )).fetchall(): for hostname in hostname_str.split(','): machine = machine_dct[hostname] calc_dir = pj(calc_root, 'calc_%s' % machine.hostname, str(idx)) for base in ['pw.in', machine.get_jobfile_basename()]: fn = pj(calc_dir, base) assert os.path.exists(fn) lines = common.file_readlines(fn) # assemble all possible replacements in one list of SQLEntry # instances, some things are redundantely checked twice ... sql_lst = params_lst[idx] + list( machine.get_sql_record().values()) for db_key in db_colnames: db_val = db.get_single( "select %s from calc " "where idx==?" % db_key, (idx, )) if db_val is not None: sql_lst.append(sql.SQLEntry(key=db_key, sqlval=db_val)) # for each replacement key, check if they are correctly placed # in the database (if applicable) and in the written files for sqlentry in sql_lst: if sqlentry.key in db_colnames: db_val = db.get_single("select %s from calc " "where idx==?" \ %sqlentry.key, (idx,)) assert_all_types_equal(db_val, sqlentry.sqlval) else: db_val = 'NOT_DEFINED_IN_DB' print("check_generated: idx={0}, sqlentry.key={1}, " "sqlentry.sqlval={2}, db_val={3}".format( idx, sqlentry.key, sqlentry.sqlval, db_val)) check_key_in_file(lines, sqlentry.key, sqlentry.sqlval) db.finish()
def check_generated(calc_root, machine_dct, params_lst, revision): """Check consistency of calc database values, replacement params in `params_lst` and all written files. """ db = sql.SQLiteDB(pj(calc_root, 'calc.db'), table='calc') db_colnames = [x[0] for x in db.get_header()] for idx,hostname_str in db.execute("select idx,hostname from calc \ where revision==?", (revision,)).fetchall(): for hostname in hostname_str.split(','): machine = machine_dct[hostname] calc_dir = pj(calc_root, 'calc_%s' %machine.hostname, str(idx)) for base in ['pw.in', machine.get_jobfile_basename()]: fn = pj(calc_dir, base) assert os.path.exists(fn) lines = common.file_readlines(fn) # assemble all possible replacements in one list of SQLEntry # instances, some things are redundantely checked twice ... sql_lst = params_lst[idx] + machine.get_sql_record().values() for db_key in db_colnames: db_val = db.get_single("select %s from calc " "where idx==?" %db_key, (idx,)) if db_val is not None: sql_lst.append(sql.SQLEntry(key=db_key, sqlval=db_val)) # for each replacement key, check if they are correctly placed # in the database (if applicable) and in the written files for sqlentry in sql_lst: if sqlentry.key in db_colnames: db_val = db.get_single("select %s from calc " "where idx==?" \ %sqlentry.key, (idx,)) assert_all_types_equal(db_val, sqlentry.sqlval) else: db_val = 'NOT_DEFINED_IN_DB' print("check_generated: idx={0}, sqlentry.key={1}, " "sqlentry.sqlval={2}, db_val={3}".format(idx, sqlentry.key, sqlentry.sqlval, db_val)) check_key_in_file(lines, sqlentry.key, sqlentry.sqlval) db.finish()
def read_matdyn_freq(filename): """Parse frequency file produced by QE's matdyn.x ("flfrq" in matdyn.x input, usually "matdyn.freq" or so) when calculating a phonon dispersion on a grid (ldisp=.true., used for phonon dos) or a pre-defined k-path in the BZ. In QE 5.x, a file with suffix ".gp" (e.g. "matdyn.freq.gp") is now written, where:: >>> import numpy as np >>> from pwtools import kpath, pwscf >>> d = np.loadtxt("matdyn.freq.gp") >>> kpoints,freqs = pwscf.read_matdyn_freq("matdyn.freq") >>> allclose(d[:,0], kpath.get_path_norm(kpoints)) >>> allclose(d[:,1:], freqs) Parameters ---------- filename : file with k-points and phonon frequencies Returns ------- kpoints : array (nks, 3) Array with `nks` k-points. AFAIK the unit is always ``2*pi/alat`` with ``alat = celldm(1)``. freqs : array (nks, nbnd) Array with `nbnd` energies/frequencies at each of the `nks` k-points. For phonon DOS, nbnd == 3*natoms. Notes ----- `matdyn.in`:: &input asr='simple', amass(1)=26.981538, amass(2)=14.00674, flfrc='fc', flfrq='matdyn.freq.disp' / 101 | nks 0.000000 0.000000 0.000000 | 0.037500 0.037500 0.000000 | List of nks = 101 k-points .... | `filename` has the form:: <header> <k-point, (3,)> <frequencies,(nbnd,) <k-point, (3,)> <frequencies,(nbnd,) ... for example:: &plot nbnd= 6, nks= 101 / 0.000000 0.000000 0.000000 0.0000 0.0000 0.0000 456.2385 456.2385 871.5931 0.037500 0.037500 0.000000 23.8811 37.3033 54.3776 455.7569 457.2338 869.8832 ..... See Also -------- bin/plot_dispersion.py, :func:`pwtools.kpath.plot_dis`, :func:`pwtools.kpath.get_path_norm` """ lines = file_readlines(filename) # Read number of bands (nbnd) and k-points (nks). OK, Fortran's namelists # win here :) # nbnd: number of bands = number of frequencies per k-point = 3*natoms for # phonons # nks: number of k-points pat = r'.*\s+nbnd\s*=\s*([0-9]+)\s*,\s*nks\s*=\s*([0-9]+)\s*/' match = re.match(pat, lines[0]) assert (match is not None), "match is None" nbnd = int(match.group(1)) nks = int(match.group(2)) kpoints = np.empty((nks, 3), dtype=float) freqs = np.empty((nks, nbnd), dtype=float) step = 3 + nbnd # nasty trick: join all lines containing data into one 1d array: " ".join() # does "1 2\n3 4" -> "1 2\n 3 4" and split() splits at \n + whitespace. items = np.array(' '.join(lines[1:]).split(), dtype=float) for ii in range(len(items) / step): kpoints[ii,:] = items[ii*step:(ii*step+3)] freqs[ii,:] = items[(ii*step+3):(ii*step+step)] return kpoints, freqs
def read_matdyn_freq(filename): """Parse frequency file produced by QE's matdyn.x ("flfrq" in matdyn.x input, usually "matdyn.freq" or so) when calculating a phonon dispersion on a grid (ldisp=.true., used for phonon dos) or a pre-defined k-path in the BZ. In QE 5.x, a file with suffix ".gp" (e.g. "matdyn.freq.gp") is now written, where:: >>> import numpy as np >>> from pwtools import kpath, pwscf >>> d = np.loadtxt("matdyn.freq.gp") >>> kpoints,freqs = pwscf.read_matdyn_freq("matdyn.freq") >>> allclose(d[:,0], kpath.get_path_norm(kpoints)) >>> allclose(d[:,1:], freqs) Parameters ---------- filename : file with k-points and phonon frequencies Returns ------- kpoints : array (nks, 3) Array with `nks` k-points. AFAIK the unit is always ``2*pi/alat`` with ``alat = celldm(1)``. freqs : array (nks, nbnd) Array with `nbnd` energies/frequencies at each of the `nks` k-points. For phonon DOS, nbnd == 3*natoms. Notes ----- `matdyn.in`:: &input asr='simple', amass(1)=26.981538, amass(2)=14.00674, flfrc='fc', flfrq='matdyn.freq.disp' / 101 | nks 0.000000 0.000000 0.000000 | 0.037500 0.037500 0.000000 | List of nks = 101 k-points .... | `filename` has the form:: <header> <k-point, (3,)> <frequencies,(nbnd,) <k-point, (3,)> <frequencies,(nbnd,) ... for example:: &plot nbnd= 6, nks= 101 / 0.000000 0.000000 0.000000 0.0000 0.0000 0.0000 456.2385 456.2385 871.5931 0.037500 0.037500 0.000000 23.8811 37.3033 54.3776 455.7569 457.2338 869.8832 ..... See Also -------- bin/plot_dispersion.py, :func:`pwtools.kpath.plot_dis`, :func:`pwtools.kpath.get_path_norm` """ lines = file_readlines(filename) # Read number of bands (nbnd) and k-points (nks). OK, Fortran's namelists # win here :) # nbnd: number of bands = number of frequencies per k-point = 3*natoms for # phonons # nks: number of k-points pat = r'.*\s+nbnd\s*=\s*([0-9]+)\s*,\s*nks\s*=\s*([0-9]+)\s*/' match = re.match(pat, lines[0]) assert (match is not None), "match is None" nbnd = int(match.group(1)) nks = int(match.group(2)) kpoints = np.empty((nks, 3), dtype=float) freqs = np.empty((nks, nbnd), dtype=float) step = 3 + nbnd # nasty trick: join all lines containing data into one 1d array: " ".join() # does "1 2\n3 4" -> "1 2\n 3 4" and split() splits at \n + whitespace. items = np.array(' '.join(lines[1:]).split(), dtype=float) for ii in range(len(items) // step): kpoints[ii,:] = items[ii*step:(ii*step+3)] freqs[ii,:] = items[(ii*step+3):(ii*step+step)] return kpoints, freqs