예제 #1
0
def progress_bar(proc, func_input_dict, tail_line_num=20):
    """ Monitor ``.log`` file timestep.
    The ``func_input_dict`` should contains several keys:

    * `nsteps`: Total number of steps during the simulation
    * `log`: path of the log file (Defined in ``os_command.run_background()``)
    * `refresh_time`: time interval to refresh log extract (default=1.0 s)

    :param proc: running subprocess
    :type proc: subprocess object

    :param func_input_dict: dictionnary containing parameters for log extract
    :type func_input_dict: dict

    :param tail_line_num: number of line to read at the end of ``.log`` file
    :type tail_line_num: int, default=20


    Example:

    >>> TEST_OUT = str(getfixture('tmpdir'))
    >>> import sys
    >>> sys.path.insert(0, os.path.abspath(os.path.join(MONITOR_LIB_DIR, \
'../..')))
    >>> from gromacs_py import gmx #doctest: +NORMALIZE_WHITESPACE, +ELLIPSIS
    <BLANKLINE>
    ...
    >>> prot = gmx.GmxSys(name='1y0m', coor_file=TEST_PATH+'/1y0m.pdb')
    >>> ###################################
    >>> ####   Create the topologie:   ###
    >>> ###################################
    >>> prot.prepare_top(out_folder=os.path.join(TEST_OUT, 'top_SH3'), \
vsite='hydrogens') #doctest: +ELLIPSIS
    pdb2pqr... --ff CHARMM --ffout CHARMM --chain --ph-calc-method=propka \
--with-ph=7.00 tmp_pdb2pqr.pdb 00_1y0m.pqr
    gmx pdb2gmx -f 01_1y0m_good_his.pdb -o 1y0m_pdb2gmx.pdb -p \
1y0m_pdb2gmx.top -i 1y0m_posre.itp -water tip3p -ff charmm36-jul2017 -ignh \
-vsite hydrogens
    >>> ######################################
    >>> ### Monitor an energy minimisation ###
    >>> ######################################
    >>> monitor = PROGRESS_BAR
    >>> prot.em(out_folder=os.path.join(TEST_OUT, 'em_SH3'), nsteps=50,\
    constraints='none', create_box_flag=True, monitor=monitor, nstlog=1)\
    #doctest: +ELLIPSIS
    gmx editconf -f .../top_SH3/1y0m_pdb2gmx.pdb -o \
.../top_SH3/1y0m_pdb2gmx_box.pdb -bt dodecahedron -d 1.0
    gmx grompp -f 1y0m.mdp -c ../top_SH3/1y0m_pdb2gmx_box.pdb -r \
../top_SH3/1y0m_pdb2gmx_box.pdb -p ../top_SH3/1y0m_pdb2gmx.top -po \
out_1y0m.mdp -o 1y0m.tpr -maxwarn 1
    gmx mdrun -s 1y0m.tpr -deffnm 1y0m -nt 0 -ntmpi 0 -nsteps -2 \
-nocopyright

    """

    if isnotebook():
        from tqdm.notebook import tqdm
    else:
        from tqdm import tqdm

    log_to_check = func_input_dict['log']
    time_modif = None
    file_time = None
    count = 1
    if 'refresh_time' in func_input_dict:
        refresh_time = func_input_dict['refresh_time']
    else:
        refresh_time = 1.0

    pbar = tqdm(total=func_input_dict['nsteps'])
    last_time = 0

    while proc.poll() is None:

        time.sleep(refresh_time)
        count += 1

        if os_command.check_file_exist(log_to_check):
            file_time = os.stat(log_to_check).st_mtime

        if time_modif != file_time:

            time_modif = file_time

            log_dict = extract_log_dict(func_input_dict)
            if 'step' in log_dict:
                pbar.update(log_dict['step'] - last_time)
                last_time = log_dict['step']

    pbar.update(func_input_dict['nsteps'] - last_time)
    pbar.close()
예제 #2
0
def print_log_file(proc, func_input_dict, tail_line_num=20):
    """ Monitor ``.log`` file information.
    The ``func_input_dict`` should contains several keys:

    * `terms`: list of energetic terms to extract, eg. ['Potential',
        'Temperature']
    * `log`: path of the log file (Defined in ``os_command.run_background()``)
    * `refresh_time`: time interval to refresh log extract (default=1.0 s)

    :param proc: running subprocess
    :type proc: subprocess object

    :param func_input_dict: dictionnary containing parameters for log extract
    :type func_input_dict: dict

    :param tail_line_num: number of line to read at the end of ``.log`` file
    :type tail_line_num: int, default=20


    Example:

    >>> TEST_OUT = str(getfixture('tmpdir'))
    >>> import sys
    >>> sys.path.insert(0, os.path.abspath(os.path.join(MONITOR_LIB_DIR, \
'../..')))
    >>> from gromacs_py import gmx #doctest: +NORMALIZE_WHITESPACE, +ELLIPSIS
    <BLANKLINE>
    ...
    >>> prot = gmx.GmxSys(name='1y0m', coor_file=TEST_PATH+'/1y0m.pdb')
    >>> ###################################
    >>> ####   Create the topologie:   ###
    >>> ###################################
    >>> prot.prepare_top(out_folder=os.path.join(TEST_OUT, 'top_SH3'), \
vsite='hydrogens') #doctest: +ELLIPSIS
    pdb2pqr... --ff CHARMM --ffout CHARMM --chain --ph-calc-method=propka \
--with-ph=7.00 tmp_pdb2pqr.pdb 00_1y0m.pqr
    gmx pdb2gmx -f 01_1y0m_good_his.pdb -o 1y0m_pdb2gmx.pdb -p \
1y0m_pdb2gmx.top -i 1y0m_posre.itp -water tip3p -ff charmm36-jul2017 -ignh \
-vsite hydrogens
    >>> ######################################
    >>> ### Monitor an energy minimisation ###
    >>> ######################################
    >>> monitor = {'function': print_log_file,\
           'terms':['Potential'],\
           'file_check_ext':'log'}
    >>> prot.em(out_folder=os.path.join(TEST_OUT, 'em_SH3'), nsteps=50,\
    constraints='none', create_box_flag=True, monitor=monitor, nstlog=1)\
    #doctest: +ELLIPSIS
    gmx editconf -f .../top_SH3/1y0m_pdb2gmx.pdb -o \
.../top_SH3/1y0m_pdb2gmx_box.pdb -bt dodecahedron -d 1.0
    gmx grompp -f 1y0m.mdp -c ../top_SH3/1y0m_pdb2gmx_box.pdb -r \
../top_SH3/1y0m_pdb2gmx_box.pdb -p ../top_SH3/1y0m_pdb2gmx.top -po \
out_1y0m.mdp -o 1y0m.tpr -maxwarn 1
    gmx mdrun -s 1y0m.tpr -deffnm 1y0m -nt 0 -ntmpi 0 -nsteps -2 \
-nocopyright...

    """

    log_to_check = func_input_dict['log']
    time_modif = None
    file_time = None
    count = 1
    if 'refresh_time' in func_input_dict:
        refresh_time = func_input_dict['refresh_time']
    else:
        refresh_time = 1.0

    while proc.poll() is None:

        time.sleep(refresh_time)
        count += 1

        if os_command.check_file_exist(log_to_check):
            file_time = os.stat(log_to_check).st_mtime

        if time_modif != file_time:

            time_modif = file_time

            log_dict = extract_log_dict(func_input_dict)
            if 'time' in log_dict:
                print("time = {:6.1f} ".format(log_dict['time']), end='')
                for keys in func_input_dict['terms']:
                    if keys in log_dict:
                        print("  {} = {:5.1f} ".format(keys, log_dict[keys]),
                              end='')
                print()
예제 #3
0
    def correct_charge_type(self, forcefield, index_list=None):
        """ Correct the charge and atom type of an itp object,
        base on a ff `.rtp` file.
        This is specially usefull, to correct charge of termini resiudes
        of a cyclicized peptide.

        if index_list is None, will correct all atom charges, if not, only
        atoms listed in index_list.
        """

        # First extract charge and type from the ff .rtp file
        forcefield_path = forcefield['path']
        rtp_path = os.path.abspath(
            os.path.join(os_command.get_directory(forcefield_path),
                         'aminoacids.rtp'))
        if not os_command.check_file_exist(rtp_path):
            rtp_path = os.path.abspath(
                os.path.join(os_command.get_directory(forcefield_path),
                             'merged.rtp'))

        logger.info('Read rtp file : {}'.format(rtp_path))
        ff_rtp = Rtp(rtp_path)

        # Correct charges and type:
        # for atom_num, atom in self.atom_dict.items():
        if index_list is None:
            index_list = self.atom_dict.keys()

        for atom_num in index_list:

            atom = self.atom_dict[atom_num]

            res_name = atom['res_name']
            resid = atom['res_num']
            atom_name = atom['atom_name']

            # With Amber disulfide cys are called CYX in the rtp and CYS in
            # the itp.
            # Don't get sense but need to check the protonation state of cys
            # By counting atoms
            # With charmm disuldie cys is CYS2
            if res_name == 'CYS':
                if len(
                        self.get_selection_index(selec_dict={
                            'res_num': [resid],
                            'res_name': ['CYS']
                        })) == 10:
                    if forcefield['name'].startswith('amber'):
                        res_name = 'CYX'
                    elif forcefield['name'].startswith('charmm'):
                        res_name = 'CYS2'
            # print(res_name)
            # With gromacs all histidine are called HIS !
            if res_name == 'HIS':
                if len(
                        self.get_selection_index(selec_dict={
                            'res_num': [resid],
                            'res_name': ['HIS']
                        })) == 18:
                    if forcefield['name'].startswith('amber'):
                        res_name = 'HIP'
                    elif forcefield['name'].startswith('charmm'):
                        res_name = 'HSP'
                elif len(
                        self.get_selection_index(selec_dict={
                            'res_num': [resid],
                            'atom_name': ['HE2']
                        })) == 1:
                    if forcefield['name'].startswith('amber'):
                        res_name = 'HIE'
                    elif forcefield['name'].startswith('charmm'):
                        res_name = 'HSE'
                else:
                    if forcefield['name'].startswith('amber'):
                        res_name = 'HID'
                    elif forcefield['name'].startswith('charmm'):
                        res_name = 'HSD'

            # print(atom)
            # print(ff_rtp.res_dict[res_name]['atom'][atom_name])

            if atom_name in ff_rtp.res_dict[res_name]['atom']:
                atom_type = \
                    ff_rtp.res_dict[res_name]['atom'][atom_name]['type']
                atom_charge = \
                    ff_rtp.res_dict[res_name]['atom'][atom_name]['charge']
                # print('Correct residue {:4} atom {:4} atom type {:4} '
                #       'to {:4}'.format(res_name, atom['atom_name'],
                #                        atom['atom_type'], atom_type))
                # print('Correct charge {:4} '
                #       'to {:4}'.format(self.atom_dict[atom_num]['charge'],
                #                        atom_charge))
                if atom_type != atom['atom_type']:
                    logger.warning('Correct residue {:4} atom {:4} atom '
                                   'type {:4} to {:4}'.format(
                                       res_name, atom['atom_name'],
                                       atom['atom_type'], atom_type))
            else:
                logger.warning('Can\'t find residue {:4} atom {:4} atom '
                               'type {:4} parameters in forcefield'.format(
                                   res_name, atom['atom_name'],
                                   atom['atom_type']))
            self.atom_dict[atom_num]['atom_type'] = atom_type
            self.atom_dict[atom_num]['charge'] = atom_charge
예제 #4
0
def simulation_plot(proc, func_input_dict, refresh_time=1.0):
    """ This function is used for monitoring a simulation in real time.
    Function can be excecuted by the gromacs.tools.os_command.run_background()
    function.
    The function monitors a trajectory file, and launch the analysis if the
    file has been modified.
    It can plot as function of time an analysis of a simulation.
    Analysis is passed as input function.

    .. warning::
        Need to add the following lines to be run in jupyter notebook:

        * ``%matplotlib notebook``

    Example:

    >>> TEST_OUT = str(getfixture('tmpdir'))
    >>> import sys
    >>> # print(os.path.abspath(os.path.join(MONITOR_LIB_DIR, \
'../..')))
    >>> sys.path.insert(0, os.path.abspath(os.path.join(MONITOR_LIB_DIR, \
'../..')))
    >>> from gromacs_py import gmx #doctest: +ELLIPSIS
    >>> prot = gmx.GmxSys(name='1y0m', coor_file=TEST_PATH+'/1y0m.pdb')
    >>> ###################################
    >>> ####   Create the topologie:   ###
    >>> ###################################
    >>> prot.prepare_top(out_folder=os.path.join(TEST_OUT, 'top_SH3'), \
vsite='hydrogens') #doctest: +ELLIPSIS
    pdb2pqr... --ff CHARMM --ffout CHARMM --chain --ph-calc-method=propka \
--with-ph=7.00 tmp_pdb2pqr.pdb 00_1y0m.pqr
    gmx pdb2gmx -f 01_1y0m_good_his.pdb -o 1y0m_pdb2gmx.pdb -p \
1y0m_pdb2gmx.top -i 1y0m_posre.itp -water tip3p -ff charmm36-jul2017 -ignh \
-vsite hydrogens
    >>> ######################################
    >>> ### Monitor an energy minimisation ###
    >>> ######################################
    >>> monitor = {'function': simulation_plot,\
           'extract_func': [{'func': extract_log_dict,\
                             'term': 'Potential'},\
                           {'func': extract_log_dict,\
                             'term': 'Temperature'}],\
           'file_check_ext':'log'}
    >>> prot.em(out_folder=os.path.join(TEST_OUT, 'em_SH3'), nsteps=50,\
    constraints='none', create_box_flag=True, monitor=monitor, nstlog=10)\
    #doctest: +ELLIPSIS
    gmx editconf -f ...top_SH3/1y0m_pdb2gmx.pdb -o \
...top_SH3/1y0m_pdb2gmx_box.pdb -bt dodecahedron -d 1.0
    gmx grompp -f 1y0m.mdp -c .../top_SH3/1y0m_pdb2gmx_box.pdb \
-r .../top_SH3/1y0m_pdb2gmx_box.pdb -p .../top_SH3/1y0m_pdb2gmx.top \
-po out_1y0m.mdp -o 1y0m.tpr -maxwarn 1
    gmx mdrun -s 1y0m.tpr -deffnm 1y0m -nt 0 -ntmpi 0 -nsteps -2 -nocopyright

    """

    file_to_check = func_input_dict[func_input_dict['file_check_ext']]
    function_list = func_input_dict['extract_func']
    time_modif = None
    file_time = None
    count = 1
    x_list = []
    y_list = []
    notebook = isnotebook()

    ###################
    # Set up the plot #
    ###################

    # Remove the matplotlib window buttons:
    matplotlib.rcParams['toolbar'] = 'None'
    # Create the plot in interactive mode
    plt.ion()
    # fig = plt.figure()
    fig, axarr = plt.subplots(len(function_list), sharex=True)

    for i, function in enumerate(function_list):
        y_list.append([])
        x_list.append([])
        axarr[i].set_xlabel('time (ps)')
        axarr[i].set_ylabel(function['term'])
        axarr[i].plot(x_list[i],
                      y_list[i],
                      'ko-',
                      markersize=2,
                      linewidth=0.5,
                      color='blue')
    # show the window
    # figure will be in foreground, but the user may move it to background
    if not notebook:
        fig.show()
    fig.canvas.set_window_title(file_to_check[:-4])

    while proc.poll() is None:

        time.sleep(refresh_time)
        count += 1

        if os_command.check_file_exist(file_to_check):
            file_time = os.stat(file_to_check).st_mtime

        if time_modif != file_time:

            time_modif = file_time

            for i, function in enumerate(function_list):
                anal = function['func'](func_input_dict)
                # print(anal)

                if 'time' in anal and function['term'] in anal:
                    x_list[i].append(anal['time'])
                    y_list[i].append(anal[function['term']])

                    # set plot data
                    axarr[i].lines[0].set_data(x_list[i], y_list[i])
                    # recompute the data limits
                    axarr[i].relim()
                    # automatic axis scaling
                    axarr[i].autoscale_view()
                # except KeyError:
                # print('Energy could not be extract,
                # simulation is probably finished.')

            # Update the plot and take care of window events
            # (like resizing etc.)
            fig.canvas.flush_events()
            if notebook:
                # Needed when launched in notebook
                fig.canvas.draw()
예제 #5
0
    def read_file(self, top_in):

        field = None
        ifdef = False
        bond_list = []
        angle_list = []
        dihed_list = []

        with open(top_in) as topfile:
            for line in topfile:
                # print("line: ",line)
                # Check #ifdef field:
                if line[:6] == '#ifdef':
                    ifdef = True
                if line[:6] == '#endif':
                    ifdef = False
                # Check include files
                if not ifdef and line.startswith('#include'):
                    # get the file name to include:
                    file_name = line.split()[1][1:-1]
                    # remove '"' , path and .itp:
                    include = (file_name.split("/")[-1]).split(".")[0]

                    # Look if the itp is in the top path:
                    # print("Path 1: ",self.folder+"/"+file_name)
                    # print("Path 2: ",FORCEFIELD_PATH_LIST+"/"+file_name)

                    itp_found = False
                    if os_command.check_file_exist(
                            os.path.join(self.folder, file_name)):
                        path = os.path.abspath(
                            os.path.join(self.folder, file_name))
                        itp_found = True
                    else:
                        for forcefield in FORCEFIELD_PATH_LIST:
                            if os_command.check_file_exist(
                                    os.path.join(forcefield, file_name)):
                                path = os.path.abspath(
                                    os.path.join(forcefield, file_name))
                                itp_found = True
                                break
                    if not itp_found:
                        raise IOError('Itp ' + file_name + ' not found')

                    # print("name =", include, "fullname =", file_name,
                    # "path =",path)
                    if include == "forcefield":
                        self.forcefield = {
                            'name': file_name.split('.')[0],
                            'fullname': file_name,
                            'path': path
                        }
                    else:
                        self.add_mol_itp(path)
                # Check field
                elif not ifdef and line.startswith("["):
                    # Remove space and [ ]
                    field = line.strip()[1:-1].strip()
                    # print(field)
                    # As intermolecular_inter field is empty
                    # (filled with bonds, angles, ...)
                    # It has to be checked now:
                    if field == 'intermolecular_interactions':
                        self.inter_interact = True
                    continue
                # Check in the field :
                elif (not ifdef and not line[0].startswith(";")
                      and line.strip() != ""):
                    if field == 'moleculetype':
                        # in the case where mol param are present in the top
                        # file, convert the top to an itp
                        # If mol_name variable is defined, give to the mol
                        # param this name
                        name_itp = os.path.basename(top_in)[:-3] + "itp"

                        logger.info("Molecule topologie present in {} "
                                    ", extract the topologie in a separate"
                                    " file: {}".format(top_in, name_itp))
                        # Store and write the itp file:
                        top_itp = Itp(name=name_itp,
                                      fullname=name_itp,
                                      path=os.path.abspath(top_in))
                        top_itp.write_file(os.path.join(self.folder, name_itp))
                        top_itp.display()
                        # Add the itp to the itp_list
                        self.add_mol_itp(os.path.join(self.folder, name_itp))
                        self.include_itp = True
                    # Name of the system
                    elif field == 'system':
                        self.name = line.strip()
                    # Molecule composition of the system
                    elif field == 'molecules':
                        line_list = line.strip().split()
                        self.mol_comp.append({
                            'name': line_list[0],
                            'num': line_list[1]
                        })
                    # Following command concern
                    # intermolecular interactions
                    elif field == 'bonds':
                        bond_list.append(line.strip().split())
                    elif field == 'angles':
                        angle_list.append(line.strip().split())
                    elif field == 'dihedrals':
                        dihed_list.append(line.strip().split())
        if self.inter_interact:
            self.add_intermolecular_restr(bond_list=bond_list,
                                          angle_list=angle_list,
                                          dihed_list=dihed_list)