Пример #1
0
 def distance_table(self, struc_list, mass_wt_pw, digits=4):
     """
     Return a table with the RMSDs between the structures in struc_list.
     <digits> specifies how many digits after the decimal point are printed out.
     """
     tm = file_handler.table_maker([5] + (len(struc_list)-1) * [digits+4])
     tm.write_line([''] + [struc.name for struc in struc_list[1:]])
     for i,struc1 in enumerate(struc_list[:-1]):
         tm.write_line([struc1.name] + [''] * i + [locale.format("%.*f", (digits, self.distance(struc1, struc2, mass_wt_pw=mass_wt_pw))) for struc2 in struc_list[i+1:]])
     return tm.return_table()
Пример #2
0
def ret_FRCOORD_table(struc):
    """
    Create the FRCOORD part in the molden file.
    """
    tblmaker = file_handler.table_maker([4, 21, 21, 21])
    for i in xrange(struc.ret_num_at()):
        atom = struc.mol.GetAtom(i + 1)
        vec = atom.GetVector()
        tblmaker.write_line([struc.ret_symbol(i + 1)] + [atom.x() / b_in_a] +
                            [atom.y() / b_in_a] + [atom.z() / b_in_a])

    return tblmaker.return_table()
Пример #3
0
def ret_Atoms_table(struc):
    """
    Create the atoms part in the molden file.
    """
    tblmaker = file_handler.table_maker([6, 4, 3, 21, 21, 21])
    for i in xrange(struc.ret_num_at()):
        atom = struc.mol.GetAtom(i + 1)
        tblmaker.write_line(
            [struc.ret_symbol(i + 1), i +
             1, atom.GetAtomicNum()] + [atom.x() / b_in_a] +
            [atom.y() / b_in_a] + [atom.z() / b_in_a])

    return tblmaker.return_table()
Пример #4
0
    def autocorr(self, mass_mat=None, out_file='RESULTS/autocorr.txt'):
        """
        Compute the autocorrelation function.
        """
        # +++
        tm = file_handler.table_maker(2 * [20])

        ac_list = []
        for disp in xrange(self.num_tsteps):
            print disp
            ac_list += [self.ret_autocorr_disp(disp=disp, mass_mat=mass_mat)]

        for disp in xrange(self.num_tsteps):
            tm.write_line([float(disp) * self.dt, ac_list[disp]])

        tm.write_to_file(out_file)
Пример #5
0
    def print_xyz_file(self, file_path):
        """
        Creates an xyz file with the vibrational information.
        """
        out_str = ''
        for vib in self.vibs:
            out_str += str(len(self.atoms)) + '\n'
            out_str += 'Frequency ' + str(vib.frequency) + '\n'

            tmaker = file_handler.table_maker([5] + 6 * [20])
            for at_ind, atom in enumerate(self.atoms):
                tmaker.write_line([' ' + atom.name] + atom.pos +
                                  vib.vector_list[at_ind])
            out_str += tmaker.return_table()

        xyzfile = open(file_path, 'w')
        xyzfile.write(out_str)
        xyzfile.close()
Пример #6
0
    def normal_mode_analysis(self,
                             nma_mat,
                             def_struc,
                             header=None,
                             out_file='nma.txt',
                             abs_list=[],
                             timestep=1.0):
        """
        Perform a normal mode analysis and print the result to <out_file>.
        Normal modes are specified by numpy.array <nma_mat> (in cartesian coordinates), <nma_mat> is the inverse of the normal mode matrix.
        The <def_struc> should be the same structure that trajectories were superimposed onto.
        A matrix with all the nma vectors is returned.
        <abs_list> constains a list of normal mode numbers where the absolute value is taken (the first mode's index is 1)
        """
        # +++ include weighting for every mode
        # for example according to zero point vibrations
        # abs_list would better only be considered with the averaging

        def_vect = def_struc.ret_vector()

        tm = file_handler.table_maker([35] + len(def_vect) * [20])

        if header == None: header = [i + 1 for i in xrange(len(def_vect))]
        tm.write_header_line(header[0])
        tm.write_header_line(header[1])
        tm.write_header_line(header[2])

        nma_list = []
        for istruct, structure in enumerate(self.structures):
            diff = structure.ret_vector() - def_vect
            nma_vect = numpy.dot(
                diff, nma_mat)  # one time step in the normal mode basis
            for i in abs_list:
                nma_vect[i - 1] = abs(nma_vect[i - 1])
            tm.write_line([timestep * istruct] + [coor for coor in nma_vect])
            nma_list += [nma_vect]

        tm.write_to_file(out_file)

        return numpy.array(nma_list)
Пример #7
0
def nm_analysis(INFOS):
    """
    Normal mode analysis. Typically this script is carried out.
    """
    print 'Preparing NMA ...'

    num_steps = INFOS['numsteps']
    descr = INFOS['descr']
    out_dir = os.path.join('NMA', descr)
    ref_struc_file = INFOS['refstruc']
    ref_struc_type = INFOS['reftype']
    ana_ints = INFOS['interval']
    vibration_file = INFOS['refvib']
    dt = INFOS['timestep']
    abs_list = INFOS['symmmodes']
    neg_list = INFOS['negmodes']
    plot = INFOS['plot']
    mawe = INFOS['massweight']

    try:
        os.makedirs(out_dir)
    except OSError:
        print 'Output directory could not be created. It either already exists or you do not have writing access.'


#    shutil.copy('nma.inp',out_dir)

    ref_struc = struc_linalg.structure(
        'ref_struc'
    )  # define the structure that all the time step structures are superimposed onto
    ref_struc.read_file(ref_struc_file, ref_struc_type)
    num_at = ref_struc.ret_num_at()
    mol_calc = struc_linalg.mol_calc(def_file_path=ref_struc_file,
                                     file_type=ref_struc_type)

    # read in data from the vibration file
    vmol = vib_molden.vib_molden()
    vmol.read_molden_file(vibration_file)
    nma_mat = numpy.linalg.pinv(
        vmol.ret_vib_matrix())  # this way it is a coordinate transformation
    # +++ the alternative would be an orthogonal projection, e.g. if only a few modes are chosen
    if mawe == True:
        mass_mat = mol_calc.ret_mass_matrix(
            power=0.5
        )  # the mass matrix is for the mass weighted skalar product, it is the unit matrix if mass_wt_pw=0
        nma_mat_mawe = numpy.dot(mass_mat, nma_mat)
        nma_mat = nma_mat_mawe
    header = vmol.ret_nma_header()
    #     eff_mass_array = numpy.array(vmol.ret_eff_masses(mol_calc=mol_calc, mass_wt_pw = mass_wt_pw))
    num_vib = len(nma_mat[0])

    mult_array = numpy.zeros(
        num_vib,
        float)  # for final summary files, output is multiplied with this list
    for i in xrange(num_vib):
        if i + 1 in neg_list:
            mult_array[i] = -1
        else:
            mult_array[i] = 1

    # used for computing the variance for each mode over all trajectories and timesteps
    num_points = numpy.zeros(
        len(ana_ints)
    )  # number of all timesteps in all the trajectories for each interval analysed
    sum_array = numpy.zeros(
        [len(ana_ints), num_vib],
        float)  # a number for every time interval analysed and normal mode
    sum_sq_array = numpy.zeros([len(ana_ints), num_vib], float)

    # used for computing time resolved mean and variance
    cross_num_array = numpy.zeros(num_steps)
    cross_sum_array = numpy.zeros(
        [num_steps, num_vib], float
    )  # a number for every time step and normal mode; sum, has to be divided by cross_num_array
    cross_mean_array = numpy.zeros([num_steps, num_vib],
                                   float)  # cross_sum_array / cross_num_array
    cross_sum_sq_array = numpy.zeros([num_steps, num_vib], float)

    #not_list = []

    forbidden = ['crashed', 'running', 'dead', 'dont_analyze']
    width = 30
    files = []
    ntraj = 0
    print 'Checking the directories...'
    for idir in INFOS['paths']:
        ls = os.listdir(idir)
        for itraj in ls:
            if not 'TRAJ_' in itraj:
                continue
            path = idir + '/' + itraj
            s = path + ' ' * (width - len(path))
            pathfile = path + '/output.xyz'
            if not os.path.isfile(pathfile):
                s += '%s NOT FOUND' % (pathfile)
                print s
                continue
            lstraj = os.listdir(path)
            valid = True
            for i in lstraj:
                if i.lower() in forbidden:
                    s += 'DETECTED FILE %s' % (i.lower())
                    print s
                    valid = False
                    break
            if not valid:
                continue
            s += 'OK'
            print s
            ntraj += 1
            files.append(pathfile)
    print 'Number of trajectories: %i' % (ntraj)
    if ntraj == 0:
        print 'No valid trajectories found, exiting...'
        sys.exit(0)

    #Numtraj=(last_traj+1)-first_traj
    for i in xrange(ntraj):
        #        ls=os.listdir(os.getcwd())
        #        numfile=len(ls)
        #        k=i+first_traj
        #        string=str(k).rjust(5, '0')
        #        trajfolder=None
        #        j=0
        #        for j in range(numfile):
        #            trajfolder=re.search(string,str(ls[j]))
        #            if trajfolder!=None:
        #               break
        #        trajcheck=None
        #        if trajfolder !=None:
        #           trajcheck=re.search('TRAJ',str(ls[j]))
        #        if trajcheck !=None:
        print 'Reading trajectory ' + str(files[i]) + ' ...'
        folder_name = str(files[i])[:-10]
        trajectory = traj_manip.trajectory(folder_name, ref_struc, dt=dt)

        # actual normal mode analysis
        try:
            nma_list = trajectory.normal_mode_analysis(
                nma_mat,
                ref_struc,
                header=header,
                out_file=folder_name + '/nma_' + descr + '.txt',
                abs_list=abs_list,
                timestep=dt
            )[:
              num_steps]  # +++ abs_list should actually only be considered when averaging
        except:
            print ' *** Error: Coordinate transformation failed for trajectory ' + str(
                i) + '. Is there a proper calculation?'
            print ' Trajectory skipped ...'
            #not_list += [i]
        else:
            # addition for total std and for trajectory specific average and std
            tm_traj_av = file_handler.table_maker([35] + num_vib * [20])
            tm_traj_av.write_header_line(['Nr'] + header[0][:-1])
            tm_traj_av.write_header_line(['Wavenumber (1/cm)'] + header[1][1:])
            tm_traj_av.write_header_line(['Period (fs)'] + header[2][1:])

            tm_traj_std = file_handler.table_maker([35] + num_vib * [20])
            tm_traj_std.write_header_line(['Nr'] + header[0][:-1])
            tm_traj_std.write_header_line(['Wavenumber (1/cm)'] +
                                          header[1][1:])
            tm_traj_std.write_header_line(['Period (fs)'] + header[2][1:])
            for ii, interv in enumerate(ana_ints):
                st = interv[0]
                en = interv[1]
                np = nma_list[st:en].shape[0]
                num_points[ii] += np
                sa = numpy.add.reduce(
                    nma_list[st:en])  # add the values in one column vector
                sum_array[ii] += sa
                sqa = numpy.add.reduce(nma_list[st:en]**2)
                sum_sq_array[ii] += sqa

                # determine average and std for this trajectory and interval
                if not np == 0:
                    exp = sa / np
                    exp2 = sqa / np
                    std_array = (
                        np / (np - 1) *
                        (exp2 - exp**2))**.5  # empirical standard deviation

                    tm_traj_av.write_line([str(st) + '-' + str(en)] +
                                          exp.tolist())
                    tm_traj_std.write_line([str(st) + '-' + str(en)] +
                                           std_array.tolist())

            # output of trajectory specific information
            tm_traj_av.write_to_file(
                str(folder_name) + '/nma_' + descr + '_av.txt')
            tm_traj_std.write_to_file(
                str(folder_name) + '/nma_' + descr + '_std.txt')

            # addition for time resolved trajectory averages
            for nr, tstep in enumerate(numpy.array(nma_list)):
                cross_num_array[nr] += 1
                cross_sum_array[nr] += tstep
                cross_sum_sq_array[nr] += tstep**2

    #for i in not_list:
    #   print 'TRAJ' + str(i),

    print 'Processing data ...'
    for inum, num in enumerate(cross_num_array):
        if num == 0:
            print '*** WARNING: No trajectory found for step %i. Will perform analysis only until step %i.' % (
                inum, inum - 1)
            num_steps = inum - 1
            break
            #sys.exit()

    # determine the total standard deviation
    tm_tot_std = file_handler.table_maker([35] + num_vib * [20])
    tm_tot_std.write_header_line(['Nr'] + header[0][:-1])
    tm_tot_std.write_header_line(['Wavenumber (1/cm)'] + header[1][1:])
    tm_tot_std.write_header_line(['Period (fs)'] + header[2][1:])

    for i, interv in enumerate(ana_ints):
        exp_x = sum_array[i] / num_points[i]  # expected values of x and x**2
        exp_x2 = sum_sq_array[i] / num_points[i]
        std = (num_points[i] / (num_points[i] - 1) *
               (exp_x2 - exp_x**2))**.5  # empirical standard deviation

        std = std * mult_array

        tm_tot_std.write_line([str(interv[0]) + '-' + str(interv[1])] +
                              std.tolist())

    tm_tot_std.write_to_file(out_dir + '/total_std.txt')

    # time resolved average curves
    tm_mean = file_handler.table_maker(num_vib * [20])
    tm_std = file_handler.table_maker(num_vib * [20])

    tm_mean.write_header_line(header[0][:-1])
    tm_std.write_header_line(header[0][:-1])
    tm_mean.write_header_line(header[1][1:])
    tm_std.write_header_line(header[1][1:])
    tm_mean.write_header_line(header[2][1:])
    tm_std.write_header_line(header[2][1:])

    std_list = [0 for i in xrange(num_vib)]

    for i in xrange(num_steps):
        tm_mean.write_line(
            [coor / cross_num_array[i] for coor in cross_sum_array[i]])
        cross_mean_array[i] = cross_sum_array[i] / cross_num_array[i]
        for j in xrange(num_vib):
            exp_x = cross_sum_array[i, j] / cross_num_array[i]
            exp_x2 = cross_sum_sq_array[i, j] / cross_num_array[i]
            std_list[j] = (
                cross_num_array[i] / (cross_num_array[i] - 1) *
                (exp_x2 - exp_x**2))**.5  # empirical standard deviation

        tm_std.write_line(std_list)

    tm_mean.write_to_file(out_dir + '/mean_against_time.txt')
    tm_std.write_to_file(out_dir + '/std_against_time.txt')

    # get the variance of the time averaged structures
    tm_av_var = file_handler.table_maker([35] + num_vib * [20])
    tm_av_var.write_header_line(['Nr'] + header[0][:-1])
    tm_av_var.write_header_line(['Wavenumber (1/cm)'] + header[1][1:])
    tm_av_var.write_header_line(['Period (fs)'] + header[2][1:])

    for st, en in ana_ints:
        av_exp = numpy.add.reduce(cross_mean_array[st:en]) / (
            en - st
        )  # the way python defines this the field really has en-st entries, not en-st+1
        av_exp2 = numpy.add.reduce(cross_mean_array[st:en]**2) / (en - st)
        av_std_array = (
            (en - st) / (en - st - 1) *
            (av_exp2 - av_exp**2))**.5  # empirical standard deviation

        av_std_array = av_std_array * mult_array

        tm_av_var.write_line([str(st) + '-' + str(en)] + av_std_array.tolist())

    tm_av_var.write_to_file(out_dir + '/cross_av_std.txt')

    print 'Data processing finished.'

    if plot: plot_summary(INFOS)