def getVoxelDescriptors(mol, buffer, voxelsize=1): """ Calculate descriptors of atom properties for voxels in a grid bounding the Molecule object. Constructs a bounding box around Molecule with some buffer space. Then it Parameters ---------- mol : A Molecule object. buffer : float The buffer space to add to the bounding box. This adds zeros to the grid around the protein so that properties which are at the edge of the box can be found in the center of one. Should be usually set to boxsize/2. voxelsize : float The voxel size in A Returns ------- features : np.ndarray A list of boxes containing voxels and their properties centers : np.ndarray A list of the centers of all boxes """ properties = _getAtomtypePropertiesPDBQT(mol) # Calculate the bbox and the number of voxels [bbm, bbM] = boundingBox(mol) bbm -= buffer bbM += buffer N = np.ceil((bbM - bbm) / voxelsize).astype(int) # Calculate for each channel the atom sigmas multisigmas = np.zeros([mol.numAtoms, len(_order)]) sigmas = _getSigmas(mol) for i, p in enumerate(_order): multisigmas[properties[p], i] = sigmas[properties[p]] # Calculate occupancies and centers occs, centers = _getGridDescriptors(mol, bbm, N, multisigmas, voxelsize) occs = np.swapaxes(occs, 2, 3) occs = np.swapaxes(occs, 1, 2) occs = np.swapaxes(occs, 0, 1) return occs, centers
def getVoxelDescriptors(mol, usercenters=None, voxelsize=1, buffer=0, channels=None): """ Calculate descriptors of atom properties for voxels in a grid bounding the Molecule object. Constructs a bounding box around Molecule with some buffer space. Then it computes pharmacophoric-like descriptors on a defined grid. Parameters ---------- mol : A Molecule object. Needs to be read from Autodock 4 .pdbqt format usercenters : np.ndarray A 2D array specifying the centers of the voxels. If None is given, it will discretize the bounding box of the Molecule plus any buffer space requested into voxels of voxelsize. voxelsize : float The voxel size in A buffer : float The buffer space to add to the bounding box. This adds zeros to the grid around the protein so that properties which are at the edge of the box can be found in the center of one. Should be usually set to localimagesize/2. channels : np.ndarray A 2D array of size (mol.numAtoms, nchannels) where nchannels is the number of channels we want to have. Each column i then has True (or a float) in the rows of the atoms which belong to channel i and False (or 0) otherwise. Such boolean arrays can be obtained for example by using mol.atomselect. If the array is boolean, each atom will get assigned its VdW radius. If the array is float, these floats will be used as the corresponding atom radii. Make sure the numpy array is of dtype=bool if passing boolean values. If no channels are given, the default ('hydrophobic', 'aromatic', 'hbond_acceptor', 'hbond_donor', 'positive_ionizable', 'negative_ionizable', 'metal', 'occupancies') channels will be used. Returns ------- features : np.ndarray A 2D array of size (centers, channels) containing the effect of each channel in the voxel with that center. centers : np.ndarray A list of the centers of all boxes N : np.ndarray Is returned only when no user centers are passed. It corresponds to the number of centers in each of the x,y,z dimensions Examples -------- >>> mol = Molecule('3PTB') >>> mol.filter('protein') >>> features, centers, N = getVoxelDescriptors(mol, buffer=8) >>> # Features can be reshaped to a 4D array (3D for each grid center in xyz, 1D for the properties) like this: >>> features = features.reshape(N[0], N[1], N[2], features.shape[1]) >>> # The user can provide his own centers >>> features, centers = getVoxelDescriptors(mol, usercenters=[[0, 0, 0], [16, 24, -5]], buffer=8) """ if channels is None: channels = _getAtomtypePropertiesPDBQT(mol) if channels.dtype == bool: # Calculate for each channel the atom sigmas sigmas = _getRadii(mol) channels = sigmas[:, np.newaxis] * channels.astype(float) N = None if usercenters is None: # Calculate the bbox and the number of voxels [bbm, bbM] = boundingBox(mol) bbm -= buffer bbM += buffer N = np.ceil((bbM - bbm) / voxelsize).astype(int) + 1 # Calculate grid centers centers = _getGridCenters(bbm, N, voxelsize) centers2D = centers.reshape(np.prod(N), 3) else: centers2D = usercenters # Calculate features features = _getGridDescriptors(mol, centers2D, channels) if N is None: return features, centers2D else: return features, centers2D, N