Пример #1
0
    def testDel(self):
        cmd.pseudoatom('m1')

        stored.keys = []
        cmd.alter('all', 'p.foo = 123')
        cmd.alter('all', 'p.bar = "Hello World"')
        cmd.iterate('all', 'stored.keys = list(sorted(p.all))')
        self.assertEqual(stored.keys, ['bar', 'foo'])

        stored.keys = []
        cmd.alter('all', "del p['foo']")
        cmd.iterate('all', 'stored.keys = list(sorted(p.all))')
        self.assertEqual(stored.keys, ['bar'])

        stored.keys = []
        cmd.alter('all', "p.bar = None")
        cmd.iterate('all', 'stored.keys = list(sorted(p.all))')
        self.assertEqual(stored.keys, [])

        # object-level
        cmd.set_property('bla', 456, 'm1')
        stored.keys = cmd.get_property_list('m1')
        self.assertEqual(stored.keys, ['bla'])
        cmd.set_property('bla', None, 'm1')
        stored.keys = cmd.get_property_list('m1')
        self.assertEqual(stored.keys, [])
Пример #2
0
    def testSimple(self):
        cmd.fab('A', 'm1')
        cmd.fab('A', 'm2')
        v1 = 'foo'
        v2 = 'bar'
        v3 = 'com'
        
        # single state
        cmd.set_property('filename', v1, 'm1')
        self.assertTrue('foo' == v1)
        self.assertTrue(cmd.get_property('filename', 'm1') == v1)
        self.assertTrue(cmd.get_property('filename', 'm2') == None)

        # multiple objects
        cmd.set_property('filename', v1)
        self.assertTrue(cmd.get_property('filename', 'm2') == v1)

        # two states
        cmd.create('m1', 'm1', 1, 2)
        self.assertTrue(cmd.count_states() == 2)

        # set for all states
        cmd.set_property('filename', v1, 'm1')
        self.assertTrue(cmd.get_property('filename', 'm1', 2) == v1)

        # set for particular state
        cmd.set_property('filename', v2, 'm1', 2)
        self.assertTrue(cmd.get_property('filename', 'm1', 1) == v1)
        self.assertTrue(cmd.get_property('filename', 'm1', 2) == v2)

        # set for current state
        cmd.frame(2)
        cmd.set_property('filename', v3, 'm1', -1)
        self.assertTrue(cmd.get_property('filename', 'm1', 1) == v1)
        self.assertTrue(cmd.get_property('filename', 'm1', 2) == v3)
Пример #3
0
    def testSimple(self):
        cmd.fab('A', 'm1')
        cmd.fab('A', 'm2')
        v1 = 'foo'
        v2 = 'bar'
        v3 = 'com'
        
        # single state
        cmd.set_property('filename', v1, 'm1')
        self.assertTrue('foo' == v1)
        self.assertTrue(cmd.get_property('filename', 'm1') == v1)
        self.assertTrue(cmd.get_property('filename', 'm2') == None)

        # multiple objects
        cmd.set_property('filename', v1)
        self.assertTrue(cmd.get_property('filename', 'm2') == v1)

        # two states
        cmd.create('m1', 'm1', 1, 2)
        self.assertTrue(cmd.count_states() == 2)

        # set for all states
        cmd.set_property('filename', v1, 'm1')
        self.assertTrue(cmd.get_property('filename', 'm1', 2) == v1)

        # set for particular state
        cmd.set_property('filename', v2, 'm1', 2)
        self.assertTrue(cmd.get_property('filename', 'm1', 1) == v1)
        self.assertTrue(cmd.get_property('filename', 'm1', 2) == v2)

        # set for current state
        cmd.frame(2)
        cmd.set_property('filename', v3, 'm1', -1)
        self.assertTrue(cmd.get_property('filename', 'm1', 1) == v1)
        self.assertTrue(cmd.get_property('filename', 'm1', 2) == v3)
Пример #4
0
    def testStringType(self, str1, str2):
        cmd.fragment('ala')
        cmd.set_property('string_property_1', str1, 'ala')
        cmd.set_property('string_property_2', str2, 'ala')
        self.assertEqual(cmd.get_property('string_property_1', 'ala'), str1)
        self.assertEqual(cmd.get_property('string_property_2', 'ala'), str2)

        # test setting boolean type by string
        cmd.set_property('string_property_1', str1, 'ala', proptype=PROPERTY_STRING)
        cmd.set_property('string_property_2', str1, 'ala', proptype=PROPERTY_STRING)
        self.assertEqual(cmd.get_property('string_property_1', 'ala'), str1)
        self.assertEqual(cmd.get_property('string_property_2', 'ala'), str1)   # overwritting 
Пример #5
0
    def test(self):
        cmd.fragment('gly')

        # atom properties
        cmd.alter('index 2-4', 'p.r_custom_indexhalve = index / 2.0')
        cmd.alter('index 3-5', 'p.neg_index = -index')
        cmd.alter('elem C', 'p["spaced resn name"] = resn + " " + name')

        # object properties
        objprops = [
            ('first', 'Max'),
            ('last', 'Mustermann'),
            ('full name', 'Max Mustermann'),
            ('quoted "name"', 'Max "Mustermann"'),
        ]
        for (key, value) in objprops:
            cmd.set_property(key, value)

        # save/load round-trip
        with testing.mktemp('.mae') as filename:
            cmd.save(filename)
            cmd.delete('*')
            cmd.set('load_object_props_default', '*')
            cmd.set('load_atom_props_default', '*')
            cmd.load(filename, 'm1')

        # type conversions
        cmd.alter('m1', 'p.neg_index = int(p.s_pymol_neg_index or 0)')

        # atom properties
        self.assertEqual(2, cmd.count_atoms('p.neg_index < -3'))
        self.assertEqual(2, cmd.count_atoms('p.r_custom_indexhalve > 1.0'))

        # changed in 2.3.1: undefined (<>) -> None
        resnname = set()
        cmd.iterate('m1', 'resnname.add(p["s_pymol_spaced resn name"] or "")', space=locals())
        self.assertEqual(resnname, set(['GLY C', 'GLY CA', '']))

        # object properties
        for (key, value) in objprops:
            self.assertEqual(cmd.get_property('s_pymol_' + key, 'm1'), value)
Пример #6
0
    def testStringType(self, str1, str2):
        cmd.fragment('ala')
        cmd.set_property('string_property_1', str1, 'ala')
        cmd.set_property('string_property_2', str2, 'ala')
        self.assertEqual(cmd.get_property('string_property_1', 'ala'), str1)
        self.assertEqual(cmd.get_property('string_property_2', 'ala'), str2)

        # test setting boolean type by string
        cmd.set_property('string_property_1',
                         str1,
                         'ala',
                         proptype=PROPERTY_STRING)
        cmd.set_property('string_property_2',
                         str1,
                         'ala',
                         proptype=PROPERTY_STRING)
        self.assertEqual(cmd.get_property('string_property_1', 'ala'), str1)
        self.assertEqual(cmd.get_property('string_property_2', 'ala'),
                         str1)  # overwritting
Пример #7
0
 def testColorType(self, color1, color2):
     # colors are saved as integers, but can be accessed/set by either strings or hex
     from pymol.querying import get_color_index_from_string_or_list
     val1 = get_color_index_from_string_or_list(color1, _self=cmd)
     val2 = get_color_index_from_string_or_list(color2, _self=cmd)
     cmd.fragment('ala')
     cmd.set_property('color_property_1', color1, 'ala', proptype=PROPERTY_COLOR)
     cmd.set_property('color_property_2', color2, 'ala', proptype=PROPERTY_COLOR)
     self.assertColorEqual(cmd.get_property('color_property_1', 'ala'), val1)
     self.assertColorEqual(cmd.get_property('color_property_2', 'ala'), val2)
     self.assertColorEqual(cmd.get_property('color_property_1', 'ala'), color1)
     self.assertColorEqual(cmd.get_property('color_property_2', 'ala'), color2)
     cmd.set_property('color_property_1', str(val1), 'ala', proptype=PROPERTY_COLOR)
     cmd.set_property('color_property_2', str(val1), 'ala', proptype=PROPERTY_COLOR)
     cmd.set_property('color_property_3', str(val1), 'ala', proptype=PROPERTY_COLOR)
     cmd.set_property('color_property_4', str(val2), 'ala', proptype=PROPERTY_COLOR)
     self.assertColorEqual(cmd.get_property('color_property_1', 'ala'), color1)
     self.assertColorEqual(cmd.get_property('color_property_1', 'ala'), val1)
     self.assertColorEqual(cmd.get_property('color_property_2', 'ala'), color1)   # overwritting 
     self.assertColorEqual(cmd.get_property('color_property_2', 'ala'), val1)
     self.assertColorEqual(cmd.get_property('color_property_3', 'ala'), color1)
     self.assertColorEqual(cmd.get_property('color_property_3', 'ala'), val1)
     self.assertColorEqual(cmd.get_property('color_property_4', 'ala'), color2)
     self.assertColorEqual(cmd.get_property('color_property_4', 'ala'), val2)
Пример #8
0
    def testFloatType(self, val1, val2):
        cmd.fragment('ala')
        cmd.set_property('float_property_1', val1, 'ala')
        cmd.set_property('float_property_2', val2, 'ala')
        self.assertAlmostEqual(cmd.get_property('float_property_1', 'ala'), val1)
        self.assertAlmostEqual(cmd.get_property('float_property_2', 'ala'), val2)

        # test setting boolean type by string
        cmd.set_property('float_property_1', str(val1), 'ala', proptype=PROPERTY_FLOAT)
        cmd.set_property('float_property_2', str(val1), 'ala', proptype=PROPERTY_FLOAT)
        cmd.set_property('float_property_3', str(val1), 'ala', proptype=PROPERTY_FLOAT)
        cmd.set_property('float_property_4', str(val2), 'ala', proptype=PROPERTY_FLOAT)
        self.assertAlmostEqual(cmd.get_property('float_property_1', 'ala'), val1)
        self.assertAlmostEqual(cmd.get_property('float_property_2', 'ala'), val1)   # overwritting 
        self.assertAlmostEqual(cmd.get_property('float_property_3', 'ala'), val1)
        self.assertAlmostEqual(cmd.get_property('float_property_4', 'ala'), val2)
Пример #9
0
    def testIntegerType(self, val1, val2):
        cmd.fragment('ala')
        cmd.set_property('int_property_1', val1, 'ala')
        cmd.set_property('int_property_2', val2, 'ala')
        self.assertEqual(cmd.get_property('int_property_1', 'ala'), val1)
        self.assertEqual(cmd.get_property('int_property_2', 'ala'), val2)

        # test setting boolean type by string
        cmd.set_property('int_property_1', str(val1), 'ala', proptype=PROPERTY_INT)
        cmd.set_property('int_property_2', str(val1), 'ala', proptype=PROPERTY_INT)
        cmd.set_property('int_property_3', str(val1), 'ala', proptype=PROPERTY_INT)
        cmd.set_property('int_property_4', str(val2), 'ala', proptype=PROPERTY_INT)
        self.assertEqual(cmd.get_property('int_property_1', 'ala'), val1)
        self.assertEqual(cmd.get_property('int_property_2', 'ala'), val1)   # overwritting 
        self.assertEqual(cmd.get_property('int_property_3', 'ala'), val1)
        self.assertEqual(cmd.get_property('int_property_4', 'ala'), val2)
Пример #10
0
    def testBooleanType(self):
        cmd.fragment('ala')
        cmd.set_property('bool_property_1', True, 'ala')
        cmd.set_property('bool_property_2', False, 'ala')
        self.assertEqual(cmd.get_property('bool_property_1', 'ala'), True)
        self.assertEqual(cmd.get_property('bool_property_2', 'ala'), False)

        # test setting boolean type by string
        cmd.set_property('bool_property_1', "True", 'ala', proptype=PROPERTY_BOOLEAN)
        cmd.set_property('bool_property_2', "True", 'ala', proptype=PROPERTY_BOOLEAN)
        cmd.set_property('bool_property_3', "True", 'ala', proptype=PROPERTY_BOOLEAN)
        cmd.set_property('bool_property_4', "False", 'ala', proptype=PROPERTY_BOOLEAN)
        self.assertEqual(cmd.get_property('bool_property_1', 'ala'), True)
        self.assertEqual(cmd.get_property('bool_property_2', 'ala'), True)   # overwritting 
        self.assertEqual(cmd.get_property('bool_property_3', 'ala'), True)
        self.assertEqual(cmd.get_property('bool_property_4', 'ala'), False)
Пример #11
0
    def testFloatType(self, val1, val2):
        cmd.fragment('ala')
        cmd.set_property('float_property_1', val1, 'ala')
        cmd.set_property('float_property_2', val2, 'ala')
        self.assertAlmostEqual(cmd.get_property('float_property_1', 'ala'),
                               val1)
        self.assertAlmostEqual(cmd.get_property('float_property_2', 'ala'),
                               val2)

        # test setting boolean type by string
        cmd.set_property('float_property_1',
                         str(val1),
                         'ala',
                         proptype=PROPERTY_FLOAT)
        cmd.set_property('float_property_2',
                         str(val1),
                         'ala',
                         proptype=PROPERTY_FLOAT)
        cmd.set_property('float_property_3',
                         str(val1),
                         'ala',
                         proptype=PROPERTY_FLOAT)
        cmd.set_property('float_property_4',
                         str(val2),
                         'ala',
                         proptype=PROPERTY_FLOAT)
        self.assertAlmostEqual(cmd.get_property('float_property_1', 'ala'),
                               val1)
        self.assertAlmostEqual(cmd.get_property('float_property_2', 'ala'),
                               val1)  # overwritting
        self.assertAlmostEqual(cmd.get_property('float_property_3', 'ala'),
                               val1)
        self.assertAlmostEqual(cmd.get_property('float_property_4', 'ala'),
                               val2)
Пример #12
0
    def testIntegerType(self, val1, val2):
        cmd.fragment('ala')
        cmd.set_property('int_property_1', val1, 'ala')
        cmd.set_property('int_property_2', val2, 'ala')
        self.assertEqual(cmd.get_property('int_property_1', 'ala'), val1)
        self.assertEqual(cmd.get_property('int_property_2', 'ala'), val2)

        # test setting boolean type by string
        cmd.set_property('int_property_1',
                         str(val1),
                         'ala',
                         proptype=PROPERTY_INT)
        cmd.set_property('int_property_2',
                         str(val1),
                         'ala',
                         proptype=PROPERTY_INT)
        cmd.set_property('int_property_3',
                         str(val1),
                         'ala',
                         proptype=PROPERTY_INT)
        cmd.set_property('int_property_4',
                         str(val2),
                         'ala',
                         proptype=PROPERTY_INT)
        self.assertEqual(cmd.get_property('int_property_1', 'ala'), val1)
        self.assertEqual(cmd.get_property('int_property_2', 'ala'),
                         val1)  # overwritting
        self.assertEqual(cmd.get_property('int_property_3', 'ala'), val1)
        self.assertEqual(cmd.get_property('int_property_4', 'ala'), val2)
Пример #13
0
    def testBooleanType(self):
        cmd.fragment('ala')
        cmd.set_property('bool_property_1', True, 'ala')
        cmd.set_property('bool_property_2', False, 'ala')
        self.assertEqual(cmd.get_property('bool_property_1', 'ala'), True)
        self.assertEqual(cmd.get_property('bool_property_2', 'ala'), False)

        # test setting boolean type by string
        cmd.set_property('bool_property_1',
                         "True",
                         'ala',
                         proptype=PROPERTY_BOOLEAN)
        cmd.set_property('bool_property_2',
                         "True",
                         'ala',
                         proptype=PROPERTY_BOOLEAN)
        cmd.set_property('bool_property_3',
                         "True",
                         'ala',
                         proptype=PROPERTY_BOOLEAN)
        cmd.set_property('bool_property_4',
                         "False",
                         'ala',
                         proptype=PROPERTY_BOOLEAN)
        self.assertEqual(cmd.get_property('bool_property_1', 'ala'), True)
        self.assertEqual(cmd.get_property('bool_property_2', 'ala'),
                         True)  # overwritting
        self.assertEqual(cmd.get_property('bool_property_3', 'ala'), True)
        self.assertEqual(cmd.get_property('bool_property_4', 'ala'), False)
Пример #14
0
 def testColorType(self, color1, color2):
     # colors are saved as integers, but can be accessed/set by either strings or hex
     from pymol.querying import get_color_index_from_string_or_list
     val1 = get_color_index_from_string_or_list(color1, _self=cmd)
     val2 = get_color_index_from_string_or_list(color2, _self=cmd)
     cmd.fragment('ala')
     cmd.set_property('color_property_1',
                      color1,
                      'ala',
                      proptype=PROPERTY_COLOR)
     cmd.set_property('color_property_2',
                      color2,
                      'ala',
                      proptype=PROPERTY_COLOR)
     self.assertColorEqual(cmd.get_property('color_property_1', 'ala'),
                           val1)
     self.assertColorEqual(cmd.get_property('color_property_2', 'ala'),
                           val2)
     self.assertColorEqual(cmd.get_property('color_property_1', 'ala'),
                           color1)
     self.assertColorEqual(cmd.get_property('color_property_2', 'ala'),
                           color2)
     cmd.set_property('color_property_1',
                      str(val1),
                      'ala',
                      proptype=PROPERTY_COLOR)
     cmd.set_property('color_property_2',
                      str(val1),
                      'ala',
                      proptype=PROPERTY_COLOR)
     cmd.set_property('color_property_3',
                      str(val1),
                      'ala',
                      proptype=PROPERTY_COLOR)
     cmd.set_property('color_property_4',
                      str(val2),
                      'ala',
                      proptype=PROPERTY_COLOR)
     self.assertColorEqual(cmd.get_property('color_property_1', 'ala'),
                           color1)
     self.assertColorEqual(cmd.get_property('color_property_1', 'ala'),
                           val1)
     self.assertColorEqual(cmd.get_property('color_property_2', 'ala'),
                           color1)  # overwritting
     self.assertColorEqual(cmd.get_property('color_property_2', 'ala'),
                           val1)
     self.assertColorEqual(cmd.get_property('color_property_3', 'ala'),
                           color1)
     self.assertColorEqual(cmd.get_property('color_property_3', 'ala'),
                           val1)
     self.assertColorEqual(cmd.get_property('color_property_4', 'ala'),
                           color2)
     self.assertColorEqual(cmd.get_property('color_property_4', 'ala'),
                           val2)
Пример #15
0
def process_session(
    ensemble_collector,
    patterns,
    group,
    max_size,
    plot,
    plot_annot,
    plot_class,
    plot_method,
    table,
    base_root=None,
):
    """Main plugin code."""

    results = {}
    for pattern in sorted(patterns):
        for path in glob(pattern):
            if base_root is None:
                root = pm.get_legal_name(splitext(basename(path))[0])
            else:
                root = base_root
            results[root] = [], []
            ensembles, clusters = results[root]

            if group:
                root = f"{group}.{root}"
            else:
                root = root

            with disable_feedback("all", "warnings"):
                with settings(group_auto_mode=1):
                    pm.load(path)

            try:
                collected_ensembles = list(ensemble_collector(max_size))
                if len(collected_ensembles) == 0:
                    raise Exception("No ensembles found.")
            except:
                raise CmdException(f"File {path} is invalid.")

            with settings(group_auto_mode=2):
                pm.create(f"{root}.protein", "protein")
                pm.delete("protein")

                i = 0

                for ensemble in collected_ensembles:
                    klass = ensemble.klass
                    if klass:
                        i += 1
                        pm.hide("sticks", ensemble.selection)
                        pm.show("line", ensemble.selection)
                        pm.util.cbas(ensemble.selection)

                        obj = f"{root}.{klass}.{i:03}"
                        pm.create(obj, ensemble.selection)

                        if hasattr(pm, "set_property"):
                            pm.set_property("Class", ensemble.klass, obj)
                            pm.set_property("S", ensemble.strength, obj)
                            pm.set_property("S (CS0)",
                                            ensemble.clusters[0].strength, obj)
                            pm.set_property("CD",
                                            ensemble.max_center_to_center, obj)
                            pm.set_property("MD", ensemble.max_dist, obj)

                        ensemble.selection = obj
                        ensembles.append(ensemble)

                for i, cluster in enumerate(Cluster.collect_atlas()):
                    pm.hide("sticks", cluster.selection)
                    pm.show("line", cluster.selection)
                    pm.util.cbay(cluster.selection)
                    obj = f"{root}.CS.{i:03}_{cluster.strength:03}"
                    pm.create(obj, cluster.selection)
                    pm.delete(cluster.selection)
                    cluster.selection = obj
                    clusters.append(cluster)

            pm.color("yellow", f"{root}.CS.*")
            pm.color("salmon", f"{root}.B.* or {root}.Bs.* {root}.Bl.*")
            pm.color("red", f"{root}.D.* or {root}.Ds.* {root}.Dl.*")

            pm.hide("lines", f"{root}.*")
            pm.disable(f"{root}.CS")

            pm.show("mesh", f"{root}.B.* or {root}.Bs.* {root}.Bl.*")
            pm.show("mesh", f"{root}.D.* or {root}.Ds.* {root}.Dl.*")

            pm.show("mesh", f"{root}.CS.*")
            pm.hide("nb_spheres", "*label")

            pm.orient(root)

    if plot:

        roots = []
        selections = []

        for root in sorted(results):
            for ensemble in results[root][0]:
                roots.append(root)
                selections.append(ensemble.selection)

        if plot_class:
            selections = [s for s in selections if "." + plot_class + "." in s]

        matrix_sim = np.zeros((len(selections), len(selections)))
        matrix_over = np.zeros((len(selections), len(selections)))
        for i, (root1, selection1) in enumerate(zip(roots, selections)):
            for j, (root2, selection2) in enumerate(zip(roots, selections)):
                matrix_sim[i][j] = nearby_aminoacids_similarity(
                    selection1,
                    selection2,
                    polymer1=root1 + ".protein",
                    polymer2=root2 + ".protein",
                    method=plot_method,
                    verbose=False,
                )
                matrix_over[i][j] = get_fractional_overlap(selection1,
                                                           selection2,
                                                           verbose=0)

        fig, ax = plt.subplots(1, 2)

        sb.heatmap(
            matrix_sim,
            vmax=1,
            vmin=0,
            xticklabels=selections,
            yticklabels=selections,
            annot=plot_annot,
            cmap="YlGnBu",
            ax=ax[0],
        )
        sb.heatmap(
            matrix_over,
            vmax=1,
            vmin=0,
            yticklabels=selections,
            xticklabels=selections,
            annot=plot_annot,
            cmap="YlGnBu",
            ax=ax[1],
        )
        ax[0].set_title(plot_method + " coefficient")
        ax[0].set_xticklabels(selections, rotation=45, ha="right")
        ax[1].set_title("fractional overlap")
        ax[1].set_xticklabels(selections, rotation=45, ha="right")
        plt.show()

    if table:
        tmpl = Template("""
            <table>
                <tr>
                    <th>Object</th>
                    <th>Class</th>
                    <th>S</th>
                    <th>S0</th>
                    <th>CD</th>
                    <th>MD</th>
                </tr>
                {% for root in results %}
                    {% for e in results[root][0] %}
                        <tr>
                            <td>{{ e.selection }}</td>
                            <td>{{ e.klass }}</td>
                            <td>{{ e.strength }}</td>
                            <td>{{ e.strength0 }}</td>
                            <td>{{ e.max_center_to_center | round(2) }}</td>
                            <td>{{ e.max_dist | round(2) }}</td>
                        </tr>
                    {% endfor %}
                {% endfor %}
            </table>
        """)

        _, path = tempfile.mkstemp(suffix=".html")
        with open(path, "w") as fd:
            fd.write(tmpl.render(results=results))
        webbrowser.open(path)

    return results
Пример #16
0
def fetch_similar_shape3d(
    pdb_id: str,
    min_similarity: float = 0,
    max_resolution: Optional[float] = None,
    ligand: Optional[str] = None,
    dist: float = 5.0,
    compounds: str = "organic or inorganic",
    prosthetic_groups: str = "HEM FAD NAP NDP ADP FMN",
) -> [SimilarStructure]:
    """
    Fetch similar structures using the 3D-Shape algorithm.

    https://search.rcsb.org/

    OPTIONS:
        pdb_id          Reference PDB id.
        min_similarity  3D-Shape score threshold.
        max_resolution  Fetch only structures up to such resolution.
        ligand          Refrence ligand PDB id for apo evaluation.
        dist            Distance cut-off around reference ligand for apo
                        evaluation. Only used when ligand is given.
        compounds       Selection that shold be considered ligands upon apo
                        evaluation. Only used when ligand is given.
        prosthetic_groups   List of ligands to be ignored when evaluating apo.
    EXAMPLES:
        fetch_similar_shape3d 2XY9
    SEE ALSO:
        fetch_similar_blast
    """
    ret = requests.post(
        url="https://search.rcsb.org/rcsbsearch/v1/query",
        headers={"Content-Type": "application/json"},
        json={
            "query": {
                "type": "terminal",
                "service": "structure",
                "parameters": {
                    "value": {
                        "entry_id": pdb_id,
                        "assembly_id": "1"
                    },
                    "operator": "strict_shape_match",
                },
                "node_id": 1,
            },
            "return_type": "entry",
        },
    )

    similars = []
    for i, result in enumerate(ret.json()["result_set"]):
        sim = SimilarStructure(
            pdb_id=result["identifier"],
            score=result["score"],
            resolution=None,
        )

        # Chek the similarity threshold
        if sim.score < min_similarity:
            continue

        # Check the resolution
        if i >= 1 and max_resolution:
            resol = get_resolution(sim.pdb_id)
            if resol and resol > max_resolution:
                continue
            sim.resolution = resol

        # Fetch the structure
        pm.fetch(sim.pdb_id)

        if i >= 1:
            first_pdb_id = similars[0].pdb_id

            # Align
            pm.align(sim.pdb_id, first_pdb_id)

            # Check nearby non-prosthetic ligands
            # Apo detection
            if ligand:
                model = pm.get_model(f"({sim.pdb_id} and ({compounds}))"
                                     f" within {dist} of"
                                     f"({first_pdb_id} and (resn {ligand}))")
                resns = set(a.resn for a in model.atom)
                is_apo = True
                for resn in resns:
                    if resn not in prosthetic_groups.split():
                        is_apo = False
                        break
                if not is_apo:
                    pm.delete(sim.pdb_id)
                    continue

        # Set the score property
        if hasattr(pm, "set_property"):
            pm.set_property("shape3d_score", sim.score, sim.pdb_id)

        # Go on
        similars.append(sim)
    return similars