예제 #1
0
def test_binder_2():
    """
    test binder 2

    Test that the C++ binder runs
    """
    import os

    from pnab import bind

    os.chdir(os.path.dirname(os.path.realpath(__file__)))

    backbone = bind.Backbone()
    backbone.file_path = os.path.join('files', 'rna_bb.pdb')
    backbone.interconnects = [10, 1]
    backbone.linker = [13, 14]

    base = bind.Base()
    base.file_path = os.path.join('files', 'adenine.pdb')
    base.code = 'A'
    base.linker = [5, 11]
    base.name = 'Adenine'
    base.pair_name = 'Uracil'
    bases = [base]

    hp = bind.HelicalParameters()
    hp.h_twist = 32.39
    hp.h_rise = 2.53
    hp.inclination = 22.9
    hp.tip = 0.08
    hp.x_displacement = -4.54
    hp.y_displacement = -0.02

    rp = bind.RuntimeParameters()
    rp.search_algorithm = 'weighted random search'
    rp.num_steps = 1000000
    rp.ff_type = 'GAFF'
    rp.energy_filter = [2.0, 5.0, 10.0, 10000.0, 10000.0]
    rp.max_distance = 0.2
    rp.strand = ['Adenine'] * 5
    rp.num_candidates = 2

    output = bind.run(rp, backbone, bases, hp, 'test')
    print(output)
예제 #2
0
def test_binder_1():
    """
    test binder

    Test exposed C++ classes attributes and their types
    """
    from pnab import bind

    backbone = bind.Backbone()
    backbone_attr = {'file_path': str, 'interconnects': list, 'linker': list}
    assert all([i in backbone.__dir__() for i in backbone_attr])
    assert all([
        type(backbone.__getattribute__(k)) is val
        for k, val in backbone_attr.items()
    ])

    base = bind.Base()
    base_attr = {
        'name': str,
        'code': str,
        'pair_name': str,
        'file_path': str,
        'linker': list
    }
    assert all([i in base.__dir__() for i in base_attr])
    assert all([
        type(base.__getattribute__(k)) is val for k, val in base_attr.items()
    ])

    runtime_parameters = bind.RuntimeParameters()
    runtime_parameters_attr = {
        'energy_filter': list,
        'max_distance': float,
        'ff_type': str,
        'seed': int,
        'search_algorithm': str,
        'num_steps': int,
        'dihedral_step': float,
        'strand': list,
        'is_hexad': bool,
        'build_strand': list,
        'strand_orientation': list,
        'weighting_temperature': float,
        'monte_carlo_temperature': float,
        'mutation_rate': float,
        'crossover_rate': float,
        'population_size': int,
        'glycosidic_bond_distance': float,
        'num_candidates': int
    }
    assert all(
        [i in runtime_parameters.__dir__() for i in runtime_parameters_attr])
    assert all([
        type(runtime_parameters.__getattribute__(k)) is val
        for k, val in runtime_parameters_attr.items()
    ])

    helical_parameters = bind.HelicalParameters()
    helical_parameters_attr = [
        'h_twist', 'tip', 'inclination', 'h_rise', 'x_displacement',
        'y_displacement', 'twist', 'roll', 'tilt', 'rise', 'slide', 'shift',
        'buckle', 'propeller', 'opening', 'stretch', 'shear', 'stagger'
    ]

    assert all(
        [i in helical_parameters.__dir__() for i in helical_parameters_attr])
    assert all([
        type(helical_parameters.__getattribute__(i)) is float
        for i in helical_parameters_attr
    ])
    assert type(helical_parameters.__getattribute__('is_helical')) is bool
예제 #3
0
def test_helical_parameters():
    """
    Test the equivalence between helical and step parameters.

    The test compares 3 sets of values for helical and step parameters.
    Using the two schemes should give identical results for the accepted candidates.
    To ensure correct comparisons, the step parameter values are set to many digits.
    """
    import os

    from pnab import bind

    os.chdir(os.path.dirname(os.path.realpath(__file__)))

    parameters = [[[1, 2, 3, 4, 5, 6],
                   [
                       -0.4691332223, 0.3125034304, 2.9558478770,
                       -0.5222738076, 0.4178190461, 5.9626387714
                   ]],
                  [[-1, -2, -3, -4, -5, -6],
                   [
                       -0.4691332223, 0.3125034304, -2.9558478770,
                       -0.5222738076, 0.4178190461, -5.9626387714
                   ]],
                  [[-2, 5, 3, -15, 20, -40],
                   [
                       2.2177307312, 0.4662275467, 4.1753711904, 13.2973947701,
                       9.9730460776, -36.5122480218
                   ]]]

    backbone = bind.Backbone()
    backbone.file_path = os.path.join('files', 'rna_bb.pdb')
    backbone.interconnects = [10, 1]
    backbone.linker = [13, 14]

    base = bind.Base()
    base.file_path = os.path.join('files', 'adenine.pdb')
    base.code = 'A'
    base.linker = [5, 11]
    base.name = 'Adenine'
    base.pair_name = 'Uracil'
    bases = [base]

    rp = bind.RuntimeParameters()
    rp.search_algorithm = 'weighted random search'
    rp.num_steps = 10
    rp.ff_type = 'GAFF'
    rp.energy_filter = [1e10] * 5
    rp.max_distance = 1e10
    rp.strand = ['Adenine'] * 5
    rp.num_candidates = 10

    for p in parameters:
        hp = bind.HelicalParameters()
        hp.is_helical = True
        hp.x_displacement = p[0][0]
        hp.y_displacement = p[0][1]
        hp.h_rise = p[0][2]
        hp.inclination = p[0][3]
        hp.tip = p[0][4]
        hp.h_twist = p[0][5]

        output_helical = bind.run(rp, backbone, bases, hp, 'test')

        hp.is_helical = False
        hp.shift = p[1][0]
        hp.slide = p[1][1]
        hp.rise = p[1][2]
        hp.tilt = p[1][3]
        hp.roll = p[1][4]
        hp.twist = p[1][5]

        output_step = bind.run(rp, backbone, bases, hp, 'test')

        assert output_helical == output_step
예제 #4
0
    def _run(self, config):
        """!@brief Function to run one helical configuration.

        Setup the options to call the C++ code using the pybind11 bind class in @a binder.cpp.
        After the run finishes, it returns the results for processing.

        @param config (list) a list containing two entries: the list of helical parameter values for this
            configuration, and a string index for the sequnce of the run

        @returns results [prefix, header, result] A list containing the index of the run,
            a string describing the helical configuration, and a numpy array of the results

        @sa run
        @sa _single_result
        """
        config, prefix = config[0], config[1]

        # Add a header of the helical parameters
        header_dict = {'%s' %k:  '%.2f' %val for k, val in zip(self.options['HelicalParameters'], config)}
        if self._is_helical:
            header = ''.join(['%s=%s, ' %(k, header_dict[k]) for k in ['x_displacement', 'y_displacement', 'h_rise', 'inclination', 'tip', 'h_twist']])
        else:
            header = ''.join(['%s=%s, ' %(k, header_dict[k]) for k in ['shift', 'slide', 'rise', 'tilt', 'roll', 'twist']])
        header += ''.join(['%s=%s, ' %(k, header_dict[k]) for k in ['shear', 'stretch', 'stagger', 'buckle', 'propeller', 'opening']])
        header = header.strip(', ')

        # Set runtime parameters
        runtime_parameters = bind.RuntimeParameters()
        [runtime_parameters.__setattr__(k, val) for k, val in self.options['RuntimeParameters'].items()]

        # Set backbone parameters
        backbone = bind.Backbone()
        [backbone.__setattr__(k, val) for k, val in self.options['Backbone'].items()]

        # Set a list of all defined bases asd there parameters
        # We include all the bases even though not all of them are requested by the user
        py_bases = [self.options[i] for i in self.options if 'Base' in i]
        bases = [bind.Base() for i in range(len(py_bases))]
        for i, b in enumerate(py_bases):
            [bases[i].__setattr__(k, val) for k, val in b.items()]

        # Set helical parameters
        helical_parameters = bind.HelicalParameters()
        [helical_parameters.__setattr__(k, val) for k, val in zip(self.options['HelicalParameters'], config)]
        helical_parameters.is_helical = self._is_helical

        # Run code
        result = bind.run(runtime_parameters, backbone, bases, helical_parameters, prefix, self._verbose)

        # Get results from the comma-separated output string
        result = np.genfromtxt(StringIO(result), delimiter=',')

        if result.size == 0:
            result = None
        elif result.ndim == 1:
            result = result.reshape(1, len(result))

        if result is not None:
            result = result[result[:, 7].argsort()]

        results = [prefix, header, result]

        return results
예제 #5
0
    def _run(self, config):
        """!@brief Function to run one helical configuration.

        Setup the options to call the C++ code using the pybind11 bind class in @a binder.cpp.
        After the run finishes, it writes the results.
        Two files are written: 
            "prefix.yaml" contains a dictionary of the sequence of the run and the corresponding helical configuration
            "results.csv" contains the information on the accepted candidates for all of configurations

        @param config (list) a list containing two entries: the list of helical parameter values for this
            configuration, and a string index for the sequnce of the run

        @sa run
        """
        config, prefix = config[0], config[1]

        # Add a header of the helical parameters
        header_dict = {
            '%s' % k: '%.2f' % val
            for k, val in zip(self._options['HelicalParameters'], config)
        }
        units = ["A", "A", "A", "deg", "deg", "deg"]
        if self._is_helical:
            header = ''.join([
                '%s (%s): %s; ' % (k, units[i], header_dict[k])
                for i, k in enumerate([
                    'x_displacement', 'y_displacement', 'h_rise',
                    'inclination', 'tip', 'h_twist'
                ])
            ])
        else:
            header = ''.join([
                '%s (%s): %s; ' % (k, units[i], header_dict[k]) for i, k in
                enumerate(['shift', 'slide', 'rise', 'tilt', 'roll', 'twist'])
            ])
        header += ''.join([
            '%s (%s): %s; ' % (k, units[i], header_dict[k])
            for i, k in enumerate([
                'shear', 'stretch', 'stagger', 'buckle', 'propeller', 'opening'
            ])
        ])
        header = header.strip('; ')

        # Set runtime parameters
        runtime_parameters = bind.RuntimeParameters()
        [
            runtime_parameters.__setattr__(k, val)
            for k, val in self._options['RuntimeParameters'].items()
        ]

        # Set backbone parameters
        backbone = bind.Backbone()
        [
            backbone.__setattr__(k, val)
            for k, val in self._options['Backbone'].items()
        ]

        # Set a list of all defined bases asd there parameters
        # We include all the bases even though not all of them are requested by the user
        py_bases = [self._options[i] for i in self._options if 'Base' in i]
        bases = [bind.Base() for i in range(len(py_bases))]
        for i, b in enumerate(py_bases):
            [bases[i].__setattr__(k, val) for k, val in b.items()]

        # Set helical parameters
        helical_parameters = bind.HelicalParameters()
        [
            helical_parameters.__setattr__(k, val)
            for k, val in zip(self._options['HelicalParameters'], config)
        ]
        helical_parameters.is_helical = self._is_helical

        # Run code

        result = bind.run(runtime_parameters, backbone, bases,
                          helical_parameters, prefix, self._verbose)

        # Get results from the comma-separated output string
        result = np.genfromtxt(StringIO(result), delimiter=',')

        if result.size == 0:
            result = None
        elif result.ndim == 1:
            result = result.reshape(1, len(result))

        if result is not None:
            result = result[result[:, 7].argsort()]

        results = [prefix, header, result]

        # Write prefix and helical configuration
        with open('prefix.yaml', 'ab') as f:
            f.write(str.encode(yaml.dump({results[0]: results[1]})))

        # If there are no results, return
        if results[2] is None:
            return

        # Update header
        header = results[1] + '\n'

        header2 = self.header
        ## Add header entries for the dihedral angles
        for i in range(results[2].shape[1] - 8):
            header2 += ", Dihedral " + str(i + 1) + " (degrees)"

        header += header2

        # Write results to file
        fmt = "%i,%i"
        for i in range(results[2].shape[1] - 2):
            fmt += ",%.6f"
        with open('results.csv', 'ab') as f:
            np.savetxt(f, results[2], header=header, fmt=fmt)
예제 #6
0
def test_energy_filter():
    """
    test that energy filters are enforced and that the program
    generates lower energy conformers
    """
    import os
    from io import StringIO

    import numpy as np

    from pnab import bind

    os.chdir(os.path.dirname(os.path.realpath(__file__)))

    backbone = bind.Backbone()
    backbone.file_path = os.path.join('files', 'rna_bb.pdb')
    backbone.interconnects = [10, 1]
    backbone.linker = [13, 14]

    base = bind.Base()
    base.file_path = os.path.join('files', 'adenine.pdb')
    base.code = 'A'
    base.linker = [5, 11]
    base.name = 'Adenine'
    base.pair_name = 'Uracil'
    bases = [base]

    hp = bind.HelicalParameters()
    hp.h_twist = 32.39
    hp.h_rise = 2.53
    hp.inclination = 22.9
    hp.tip = 0.08
    hp.x_displacement = -4.54
    hp.y_displacement = -0.02

    rp = bind.RuntimeParameters()
    rp.search_algorithm = 'weighted monte carlo search'
    rp.num_steps = 1
    rp.ff_type = 'GAFF'
    rp.energy_filter = [1e100] * 5
    rp.max_distance = 1e100
    rp.strand = ['Adenine'] * 5

    output1 = bind.run(rp, backbone, bases, hp, '1')
    output1 = np.genfromtxt(StringIO(output1), delimiter=',')

    rp.num_steps = 1000000
    rp.energy_filter = [
        output1[3], output1[4], output1[5], output1[6], output1[7]
    ]
    rp.max_distance = 0.05

    output2 = bind.run(rp, backbone, bases, hp, '2')
    output2 = np.genfromtxt(StringIO(output2), delimiter=',')

    if output2.size == 0:
        return
    elif output2.ndim == 1:
        output2 = output2.reshape(1, len(output2))

    filter_index = [3, 4, 5, 6, 7]
    for i in filter_index:
        assert all([val < output1[i] for val in output2[:, i]])