def _get_crossminer_pharmacophore(self): """ convert a PharmacophoreModel into a crossminer pharmacophore """ # TODO: UPDATE WITH CHARGED FEATURES supported_features = {"acceptor_projected": "acceptor", "donor_projected": "donor", "ring": "apolar"} try: Pharmacophore.read_feature_definitions() except: raise ImportError("Crossminer is only available to CSD-Discovery") feature_definitions = {supported_features[fd.identifier]: fd for fd in Pharmacophore.feature_definitions.values() if fd.identifier in supported_features.keys()} model_features = [] for feat in self._features: if feat.feature_type == "negative" or feat.feature_type == "positive": print("Charged feature not currently supported in CrossMiner: Its on the TODO list") else: sphere = GeometricDescriptors.Sphere(feat.feature_coordinates, self.settings.radius) if feat.projected_coordinates: projected = GeometricDescriptors.Sphere(feat.projected_coordinates, self.settings.radius) p = Pharmacophore.Feature(feature_definitions[feat.feature_type], *[sphere, projected]) else: p = Pharmacophore.Feature(feature_definitions[feat.feature_type], sphere) model_features.append(p) if self.settings.excluded_volume: if not self.protein: print("Pharmacophore Model must have protein to calculate excluded volume") else: bs = self._get_binding_site_residues() for residue in bs.residues: mol = None mol = Molecule(identifier="temp_residue") # for a in residue.backbone_atoms: # ev = Pharmacophore.ExcludedVolume(GeometricDescriptors.Sphere(a.coordinates, 2)) # model_features.append(ev) for a in residue.backbone_atoms: mol.add_atom(a) centre = mol.centre_of_geometry() ev = Pharmacophore.ExcludedVolume(GeometricDescriptors.Sphere(centre, 2)) model_features.append(ev) return Pharmacophore.Query(model_features)
def run(self): if not os.path.exists(self.args.output_directory): os.makedirs(self.args.output_directory) Pharmacophore.read_feature_definitions() self.crystals = list(io.CrystalReader(self.args.overlay_file)) if self.args.threshold <= 0.0: self.args.threshold = (len(self.crystals)) / 2.0 if self.args.feature_definitions: self.feature_definitions = [ v for k, v in Pharmacophore.feature_definitions.items() if k in self.args.feature_definitions ] else: self.feature_definitions = [ fd for fd in Pharmacophore.feature_definitions.values() if fd.identifier != 'exit_vector' and fd.identifier != 'heavy_atom' and fd.identifier != 'hydrophobe' ] complete_set_of_features = [] for fd in self.feature_definitions: detected = [fd.detect_features(c) for c in self.crystals] all_feats = [f for l in detected for f in l] if not all_feats: continue minx = min(f.spheres[0].centre.x() for f in all_feats) miny = min(f.spheres[0].centre.y() for f in all_feats) minz = min(f.spheres[0].centre.z() for f in all_feats) maxx = max(f.spheres[0].centre.x() for f in all_feats) maxy = max(f.spheres[0].centre.y() for f in all_feats) maxz = max(f.spheres[0].centre.z() for f in all_feats) g = utilities.Grid((minx - 1., miny - 1., minz - 1.), (maxx + 1, maxy + 1, maxz + 1), 0.2) spheres = [] for f in all_feats: if f.spheres[0] in spheres: g.set_sphere(f.spheres[0].centre, f.spheres[0].radius, 0) else: spheres.append(f.spheres[0]) g.set_sphere(f.spheres[0].centre, f.spheres[0].radius, 1) islands = g.islands(self.args.threshold) print('Feature: %s, max value %.2f, n_features %d' % (fd.identifier, g.extrema[1], len(islands))) for island in islands: # how do I make a feature from an island? Location of highest value indices = island.indices_at_value(island.extrema[1]) centre = indices[0] org = island.bounding_box[0] centre = tuple(org[i] + island.spacing * centre[i] for i in range(3)) radius = 1.0 # Any other spheres? if len(all_feats[0].spheres) > 1: # Pick all features which contain centre feat_dists = {} for f in all_feats: dist, feat = (GeometricDescriptors.point_distance( f.spheres[0].centre, centre), f) if feat_dists.has_key(dist): feat_dists[dist].append(feat) else: feat_dists.update({dist: [feat]}) feat_dists = collections.OrderedDict( sorted(feat_dists.items())) shortest_distance = feat_dists.keys()[0] if len(feat_dists[shortest_distance]) > 1: new_feat = [ Pharmacophore.Feature( fd, GeometricDescriptors.Sphere(centre, radius), feat_dists[shortest_distance][i].spheres[1]) for i in range(len(feat_dists[shortest_distance])) ] else: new_feat = [ Pharmacophore.Feature( fd, GeometricDescriptors.Sphere(centre, radius), feat_dists[shortest_distance][0].spheres[1]) ] else: new_feat = [ Pharmacophore.Feature( fd, GeometricDescriptors.Sphere(centre, radius)) ] complete_set_of_features.extend(new_feat) model = Pharmacophore.Query(complete_set_of_features) model.write(os.path.join(self.args.output_directory, 'model.cm'))