예제 #1
0
def helanal_trajectory(universe,
                       selection="name CA",
                       start=None,
                       end=None,
                       begin=None,
                       finish=None,
                       matrix_filename="bending_matrix.dat",
                       origin_pdbfile="origin.pdb",
                       summary_filename="summary.txt",
                       screw_filename="screw.xvg",
                       tilt_filename="local_tilt.xvg",
                       fitted_tilt_filename="fit_tilt.xvg",
                       bend_filename="local_bend.xvg",
                       twist_filename="unit_twist.xvg",
                       prefix="helanal_",
                       ref_axis=None,
                       quiet=False):
    """Perform HELANAL_ helix analysis on all frames in *universe*.

    .. Note::

       Only a single helix is analyzed. Use the selection to specify the
       helix, e.g. with "name CA and resid 1:20" or use start=1, stop=20.

    :Arguments:
       *universe*
          :class:`~MDAnalysis.core.AtomGroup.Universe`

    :Keywords:
       *selection*
          selection string that selects Calpha atoms [``"name CA"``]
       *start*
          start residue resid
       *end*
          end residue resid
       *begin*
          start analysing for time (ps) >= *begin*; ``None`` starts from the
          beginning [``None``]
       *finish*
          stop analysis for time (ps) =< *finish*; ``None`` goes to the
          end of the trajectory [``None``]
       *matrix_filename*
          Output file- bending matrix [``"bending_matrix.dat"``]
       *origin_pdbfile*
          Output file- origin pdb file [``"origin.pdb"``]
       *summary_filename*
          Output file- all of the basic data [``"summary.txt"``]
       *screw_filename*
          Output file- local tilts of individual residues from 2 to n-1
          [``"screw.xvg"``]
       *tilt_filename*
          Output file- tilt of line of best fit applied to origin axes
          [``"local_tilt.xvg"``]
       *bend_filename*
          Output file- local bend angles between successive local helix axes
          [``"local_bend.xvg"``]
       *twist_filename*
          Output file- local unit twist between successive helix turns
          [``"unit_twist.xvg"``]
       *prefix*
          Prefix to add to all output file names; set to ``None`` to disable
          [``"helanal__"``]
       *ref_axis*
          Calculate tilt angle relative to the axis; if ``None`` then ``[0,0,1]``
          is chosen [``None``]
       *quiet*
          Suppress most diagnostic output.

    :Raises:
       FinishTimeException
          If the specified finish time precedes the specified start time or
          current time stamp of trajectory object.

    .. versionchanged:: 0.13.0
       New *quiet* keyword to silence frame progress output and most of the
       output that used to be printed to stdout is now logged to the logger
       *MDAnalysis.analysis.helanal* (at logelevel *INFO*).
    """
    if ref_axis is None:
        ref_axis = np.array([0., 0., 1.])
    else:
        # enable MDA API so that one can use a tuple of atoms or AtomGroup with
        # two atoms
        ref_axis = np.asarray(ref_axis)

    if not (start is None and end is None):
        if start is None:
            start = universe.atoms[0].resid
        if end is None:
            end = universe.atoms[-1].resid
        selection += " and resid {start:d}:{end:d}".format(**vars())
    ca = universe.select_atoms(selection)
    trajectory = universe.trajectory

    if finish is not None:
        if trajectory.ts.time > finish:
            # you'd be starting with a finish time (in ps) that has already passed or not
            # available
            raise FinishTimeException(
                'The input finish time ({finish} ps) precedes the current trajectory time of {traj_time} ps.'
                .format(finish=finish, traj_time=trajectory.time))

    if start is not None and end is not None:
        logger.info("Analysing from residue %d to %d", start, end)
    elif start is not None and end is None:
        logger.info("Analysing from residue %d to the C termini", start)
    elif start is None and end is not None:
        logger.info("Analysing from the N termini to %d", end)
    logger.info("Analysing %d/%d residues", ca.n_atoms,
                universe.atoms.n_residues)

    if prefix is not None:
        prefix = str(prefix)
        matrix_filename = prefix + matrix_filename
        origin_pdbfile = prefix + origin_pdbfile
        summary_filename = prefix + summary_filename
        screw_filename = prefix + screw_filename
        tilt_filename = prefix + tilt_filename
        fitted_tilt_filename = prefix + fitted_tilt_filename
        bend_filename = prefix + bend_filename
        twist_filename = prefix + twist_filename
    backup_file(matrix_filename)
    backup_file(origin_pdbfile)
    backup_file(summary_filename)
    backup_file(screw_filename)
    backup_file(tilt_filename)
    backup_file(fitted_tilt_filename)
    backup_file(bend_filename)
    backup_file(twist_filename)

    global_height = []
    global_twist = []
    global_rnou = []
    global_bending = []
    global_bending_matrix = []
    global_tilt = []
    global_fitted_tilts = []
    global_screw = []

    pm = ProgressMeter(trajectory.n_frames,
                       quiet=quiet,
                       format="Frame %(step)10d: %(time)20.1f ps\r")
    for ts in trajectory:
        pm.echo(ts.frame, time=ts.time)
        frame = ts.frame
        if begin is not None:
            if trajectory.time < begin:
                continue
        if finish is not None:
            if trajectory.time > finish:
                break

        ca_positions = ca.positions
        twist, bending_angles, height, rnou, origins, local_helix_axes, local_screw_angles = \
            main_loop(ca_positions, ref_axis=ref_axis)

        origin_pdb(origins, origin_pdbfile)

        #calculate local bending matrix( it is looking at all i, j combinations)
        if len(global_bending_matrix) == 0:
            global_bending_matrix = [[[] for item in local_helix_axes]
                                     for item in local_helix_axes]

        for i in range(len(local_helix_axes)):
            for j in range(i + 1, len(local_helix_axes)):
                angle = np.rad2deg(
                    np.arccos(np.dot(local_helix_axes[i],
                                     local_helix_axes[j])))
                global_bending_matrix[i][j].append(angle)
                #global_bending_matrix[j][i].append(angle)
                #global_bending_matrix[i][i].append(0.)

        fit_vector, fit_tilt = vector_of_best_fit(origins)
        global_height += height
        global_twist += twist
        global_rnou += rnou
        #global_screw.append(local_screw_angles)
        global_fitted_tilts.append(np.rad2deg(fit_tilt))

        #print out rotations across the helix to a file
        with open(twist_filename, "a") as twist_output:
            print(frame, end='', file=twist_output)
            for loc_twist in twist:
                print(loc_twist, end='', file=twist_output)
            print("", file=twist_output)

        with open(bend_filename, "a") as bend_output:
            print(frame, end='', file=bend_output)
            for loc_bend in bending_angles:
                print(loc_bend, end='', file=bend_output)
            print("", file=bend_output)

        with open(screw_filename, "a") as rot_output:
            print(frame, end='', file=rot_output)
            for rotation in local_screw_angles:
                print(rotation, end='', file=rot_output)
            print("", file=rot_output)

        with open(tilt_filename, "a") as tilt_output:
            print(frame, end='', file=tilt_output)
            for tilt in local_helix_axes:
                print(np.rad2deg(mdamath.angle(tilt, ref_axis)),
                      end='',
                      file=tilt_output)
            print("", file=tilt_output)

        with open(fitted_tilt_filename, "a") as tilt_output:
            print(frame, np.rad2deg(fit_tilt), file=tilt_output)

        if len(global_bending) == 0:
            global_bending = [[] for item in bending_angles]
            #global_tilt = [ [] for item in local_helix_axes ]
        for store, tmp in zip(global_bending, bending_angles):
            store.append(tmp)
        #for store,tmp in zip(global_tilt,local_helix_axes): store.append(mdamath.angle(tmp,ref_axis))

    twist_mean, twist_sd, twist_abdev = stats(global_twist)
    height_mean, height_sd, height_abdev = stats(global_height)
    rnou_mean, rnou_sd, rnou_abdev = stats(global_rnou)
    ftilt_mean, ftilt_sd, ftilt_abdev = stats(global_fitted_tilts)

    bending_statistics = [stats(item) for item in global_bending]
    #tilt_statistics =    [ stats(item) for item in global_tilt]

    bending_statistics_matrix = [[stats(col) for col in row]
                                 for row in global_bending_matrix]
    with open(matrix_filename, 'w') as mat_output:
        print("Mean", file=mat_output)
        for row in bending_statistics_matrix:
            for col in row:
                formatted_angle = "{0:6.1f}".format(col[0])
                print(formatted_angle, end='', file=mat_output)
            print('', file=mat_output)

        print('\nSD', file=mat_output)
        for row in bending_statistics_matrix:
            for col in row:
                formatted_angle = "{0:6.1f}".format(col[1])
                print(formatted_angle, end='', file=mat_output)
            print('', file=mat_output)

        print("\nABDEV", file=mat_output)
        for row in bending_statistics_matrix:
            for col in row:
                formatted_angle = "{0:6.1f}".format(col[2])
                print(formatted_angle, end='', file=mat_output)
            print('', file=mat_output)

    logger.info("Height: %g  SD: %g  ABDEV: %g  (Angstroem)", height_mean,
                height_sd, height_abdev)
    logger.info("Twist: %g  SD: %g  ABDEV: %g", twist_mean, twist_sd,
                twist_abdev)
    logger.info("Residues/turn: %g  SD: %g  ABDEV: %g", rnou_mean, rnou_sd,
                rnou_abdev)
    logger.info("Fitted tilt: %g  SD: %g  ABDEV: %g", ftilt_mean, ftilt_sd,
                ftilt_abdev)
    logger.info("Local bending angles:")
    residue_statistics = zip(*bending_statistics)
    measure_names = ["Mean ", "SD   ", "ABDEV"]
    if start is None:
        output = " ".join([
            "{0:8d}".format(item)
            for item in range(4,
                              len(residue_statistics[0]) + 4)
        ])
    else:
        output = " ".join([
            "{0:8d}".format(item)
            for item in range(start + 3,
                              len(residue_statistics[0]) + start + 3)
        ])
    logger.info("ResID %s", output)
    for measure, name in zip(residue_statistics, measure_names):
        output = str(name) + " "
        output += " ".join(["{0:8.1f}".format(residue) for residue in measure])
        logger.info(output)

    with open(summary_filename, 'w') as summary_output:
        print("Height:",
              height_mean,
              "SD",
              height_sd,
              "ABDEV",
              height_abdev,
              '(nm)',
              file=summary_output)
        print("Twist:",
              twist_mean,
              "SD",
              twist_sd,
              "ABDEV",
              twist_abdev,
              file=summary_output)
        print("Residues/turn:",
              rnou_mean,
              "SD",
              rnou_sd,
              "ABDEV",
              rnou_abdev,
              file=summary_output)
        print("Local bending angles:", file=summary_output)
        residue_statistics = list(zip(*bending_statistics))
        measure_names = ["Mean ", "SD   ", "ABDEV"]
        print("ResID", end='', file=summary_output)
        if start is None:
            for item in range(4, len(residue_statistics[0]) + 4):
                output = "{0:8d}".format(item)
                print(output, end='', file=summary_output)
        else:
            for item in range(start + 3,
                              len(residue_statistics[0]) + start + 3):
                output = "{0:8d}".format(item)
                print(output, end='', file=summary_output)
        print('', file=summary_output)

        for measure, name in zip(residue_statistics, measure_names):
            print(name, end='', file=summary_output)
            for residue in measure:
                output = "{0:8.1f}".format(residue)
                print(output, end='', file=summary_output)
            print('', file=summary_output)
예제 #2
0
def helanal_trajectory(universe, selection="name CA", start=None, end=None, begin=None, finish=None,
                       matrix_filename="bending_matrix.dat", origin_pdbfile="origin.pdb",
                       summary_filename="summary.txt", screw_filename="screw.xvg",
                       tilt_filename="local_tilt.xvg", fitted_tilt_filename="fit_tilt.xvg",
                       bend_filename="local_bend.xvg", twist_filename="unit_twist.xvg",
                       prefix="helanal_", ref_axis=None):
    """Perform HELANAL_ helix analysis on all frames in *universe*.

    .. Note::

       Only a single helix is analyzed. Use the selection to specify the
       helix, e.g. with "name CA and resid 1:20" or use start=1, stop=20.

    :Arguments:
       *universe*
          :class:`~MDAnalysis.core.AtomGroup.Universe`

    :Keywords:
       *selection*
          selection string that selects Calpha atoms [``"name CA"``]
       *start*
          start residue
       *end*
          end residue
       *begin*
          start analysing for time (ps) >= *begin*; ``None`` starts from the
          beginning [``None``]
       *finish*
          stop analysis for time (ps) =< *finish*; ``None`` goes to the
          end of the trajectory [``None``]
       *matrix_filename*
          Output file- bending matrix [``"bending_matrix.dat"``]
       *origin_pdbfile*
          Output file- origin pdb file [``"origin.pdb"``]
       *summary_filename*
          Output file- all of the basic data [``"summary.txt"``]
       *screw_filename*
          Output file- local tilts of individual residues from 2 to n-1
          [``"screw.xvg"``]
       *tilt_filename*
          Output file- tilt of line of best fit applied to origin axes
          [``"local_tilt.xvg"``]
       *bend_filename*
          Output file- local bend angles between successive local helix axes
          [``"local_bend.xvg"``]
       *twist_filename*
          Output file- local unit twist between successive helix turns
          [``"unit_twist.xvg"``]
       *prefix*
          Prefix to add to all output file names; set to ``None`` to disable
          [``"helanal__"``]
       *ref_axis*
          Calculate tilt angle relative to the axis; if ``None`` then ``[0,0,1]``
          is chosen [``None``]

    :Raises:
       FinishTimeException
        If the specified finish time precedes the specified start time or current time stamp of trajectory object.

    """
    if ref_axis is None:
        ref_axis = np.array([0., 0., 1.])
    else:
        # enable MDA API so that one can use a tuple of atoms or AtomGroup with
        # two atoms
        ref_axis = np.asarray(ref_axis)

    if start is None and end is None:
        pass
    else:
        if start is None:
            start = universe.atoms[0].resid
        if end is None:
            end = universe.atoms[-1].resid
        selection += " and resid %(start)d:%(end)d" % vars()
    ca = universe.select_atoms(selection)
    trajectory = universe.trajectory

    if finish is not None:
        if trajectory.ts.time > finish:  # you'd be starting with a finish time (in ps) that has already passed or not
        # available
            raise FinishTimeException(
                'The input finish time ({finish} ps) precedes the current trajectory time of {traj_time} ps.'.format(
                    finish=finish, traj_time=trajectory.time))

    if start is not None and end is not None:
        print "Analysing from residue", start, "to", end
    elif start is not None and end is None:
        print "Analysing from residue", start, "to the C termini"
    elif start is None and end is not None:
        print "Analysing from the N termini to", end
    print "Analysing %d/%d residues" % (ca.n_atoms, universe.atoms.n_residues)

    if not prefix is None:
        prefix = str(prefix)
        matrix_filename = prefix + matrix_filename
        origin_pdbfile = prefix + origin_pdbfile
        summary_filename = prefix + summary_filename
        screw_filename = prefix + screw_filename
        tilt_filename = prefix + tilt_filename
        fitted_tilt_filename = prefix + fitted_tilt_filename
        bend_filename = prefix + bend_filename
        twist_filename = prefix + twist_filename
    backup_file(matrix_filename)
    backup_file(origin_pdbfile)
    backup_file(summary_filename)
    backup_file(screw_filename)
    backup_file(tilt_filename)
    backup_file(fitted_tilt_filename)
    backup_file(bend_filename)
    backup_file(twist_filename)

    global_height = []
    global_twist = []
    global_rnou = []
    global_bending = []
    global_bending_matrix = []
    global_tilt = []
    global_fitted_tilts = []
    global_screw = []

    for ts in trajectory:
        frame = ts.frame
        if begin is not None:
            if trajectory.time < begin:
                continue
        if finish is not None:
            if trajectory.time > finish:
                break

        ca_positions = ca.coordinates()
        twist, bending_angles, height, rnou, origins, local_helix_axes, local_screw_angles = \
            main_loop(ca_positions, ref_axis=ref_axis)

        origin_pdb(origins, origin_pdbfile)

        #calculate local bending matrix( it is looking at all i, j combinations)
        if len(global_bending_matrix) == 0:
            global_bending_matrix = [[[] for item in local_helix_axes] for item in local_helix_axes]

        for i in range(len(local_helix_axes)):
            for j in range(i + 1, len(local_helix_axes)):
                angle = np.rad2deg(np.arccos(vecscaler(local_helix_axes[i], local_helix_axes[j])))
                global_bending_matrix[i][j].append(angle)
                #global_bending_matrix[j][i].append(angle)
                #global_bending_matrix[i][i].append(0.)

        fit_vector, fit_tilt = vector_of_best_fit(origins)
        global_height += height
        global_twist += twist
        global_rnou += rnou
        #global_screw.append(local_screw_angles)
        global_fitted_tilts.append(np.rad2deg(fit_tilt))

        #print out rotations across the helix to a file
        with open(twist_filename, "a") as twist_output:
            print >> twist_output, frame,
            for loc_twist in twist:
                print >> twist_output, loc_twist,
            print >> twist_output, ""

        with open(bend_filename, "a") as bend_output:
            print >> bend_output, frame,
            for loc_bend in bending_angles:
                print >> bend_output, loc_bend,
            print >> bend_output, ""

        with open(screw_filename, "a") as rot_output:
            print >> rot_output, frame,
            for rotation in local_screw_angles:
                print >> rot_output, rotation,
            print >> rot_output, ""

        with open(tilt_filename, "a") as tilt_output:
            print >> tilt_output, frame,
            for tilt in local_helix_axes:
                print >> tilt_output, np.rad2deg(vecangle(tilt, ref_axis)),
            print >> tilt_output, ""

        with open(fitted_tilt_filename, "a") as tilt_output:
            print >> tilt_output, frame, np.rad2deg(fit_tilt)

        if len(global_bending) == 0:
            global_bending = [[] for item in bending_angles]
            #global_tilt = [ [] for item in local_helix_axes ]
        for store, tmp in zip(global_bending, bending_angles):
            store.append(tmp)
        #for store,tmp in zip(global_tilt,local_helix_axes): store.append(vecangle(tmp,ref_axis))

        #simple ticker
        formated_time = "%20.1f" % trajectory.time
        frame += 1
        formated_frame = "%10d" % frame

        print '\r', formated_time, ' ps', formated_frame,

        sys.stdout.flush()

    print '\nComplete'
    twist_mean, twist_sd, twist_abdev = stats(global_twist)
    height_mean, height_sd, height_abdev = stats(global_height)
    rnou_mean, rnou_sd, rnou_abdev = stats(global_rnou)
    ftilt_mean, ftilt_sd, ftilt_abdev = stats(global_fitted_tilts)

    bending_statistics = [stats(item) for item in global_bending]
    #tilt_statistics =    [ stats(item) for item in global_tilt]

    bending_statistics_matrix = [[stats(col) for col in row] for row in global_bending_matrix]
    with open(matrix_filename, 'w') as mat_output:
        print >> mat_output, "Mean"
        for row in bending_statistics_matrix:
            for col in row:
                formatted_angle = "%6.1f" % col[0]
                print >> mat_output, formatted_angle,
            print >> mat_output, ''

        print >> mat_output, "\nSD"
        for row in bending_statistics_matrix:
            for col in row:
                formatted_angle = "%6.1f" % col[1]
                print >> mat_output, formatted_angle,
            print >> mat_output, ''

        print >> mat_output, "\nABDEV"
        for row in bending_statistics_matrix:
            for col in row:
                formatted_angle = "%6.1f" % col[2]
                print >> mat_output, formatted_angle,
            print >> mat_output, ''

    print "Height:", height_mean, "SD", height_sd, "ABDEV", height_abdev, '(Angstroem)'
    print "Twist:", twist_mean, "SD", twist_sd, "ABDEV", twist_abdev
    print "Residues/turn:", rnou_mean, "SD", rnou_sd, "ABDEV", rnou_abdev
    print "Fitted tilt:", ftilt_mean, "SD", ftilt_sd, "ABDEV", ftilt_abdev
    print "Local bending angles:"
    residue_statistics = zip(*bending_statistics)
    measure_names = ["Mean ", "SD   ", "ABDEV"]
    print "ResID",
    if start is None:
        for item in range(4, len(residue_statistics[0]) + 4):
            output = "%8d" % item
            print output,
    else:
        for item in range(start + 3, len(residue_statistics[0]) + start + 3):
            output = "%8d" % item
            print output,
    print ""
    for measure, name in zip(residue_statistics, measure_names):
        print name,
        for residue in measure:
            output = "%8.1f" % residue
            print output,
        print ''

    with open(summary_filename, 'w') as summary_output:
        print >> summary_output, "Height:", height_mean, "SD", height_sd, "ABDEV", height_abdev, '(nm)'
        print >> summary_output, "Twist:", twist_mean, "SD", twist_sd, "ABDEV", twist_abdev
        print >> summary_output, "Residues/turn:", rnou_mean, "SD", rnou_sd, "ABDEV", rnou_abdev
        print >> summary_output, "Local bending angles:"
        residue_statistics = zip(*bending_statistics)
        measure_names = ["Mean ", "SD   ", "ABDEV"]
        print >> summary_output, "ResID",
        if start is None:
            for item in range(4, len(residue_statistics[0]) + 4):
                output = "%8d" % item
                print >> summary_output, output,
        else:
            for item in range(start + 3, len(residue_statistics[0]) + start + 3):
                output = "%8d" % item
                print >> summary_output, output,
        print >> summary_output, ""

        for measure, name in zip(residue_statistics, measure_names):
            print >> summary_output, name,
            for residue in measure:
                output = "%8.1f" % residue
                print >> summary_output, output,
            print >> summary_output, ''