MayaChemTools

   1 #!/bin/env python
   2 #
   3 # File: PyMOLExtractSelection.py
   4 # Author: Manish Sud <msud@san.rr.com>
   5 #
   6 # Copyright (C) 2024 Manish Sud. All rights reserved.
   7 #
   8 # The functionality available in this script is implemented using PyMOL, a
   9 # molecular visualization system on an open source foundation originally
  10 # developed by Warren DeLano.
  11 #
  12 # This file is part of MayaChemTools.
  13 #
  14 # MayaChemTools is free software; you can redistribute it and/or modify it under
  15 # the terms of the GNU Lesser General Public License as published by the Free
  16 # Software Foundation; either version 3 of the License, or (at your option) any
  17 # later version.
  18 #
  19 # MayaChemTools is distributed in the hope that it will be useful, but without
  20 # any warranty; without even the implied warranty of merchantability of fitness
  21 # for a particular purpose.  See the GNU Lesser General Public License for more
  22 # details.
  23 #
  24 # You should have received a copy of the GNU Lesser General Public License
  25 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or
  26 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330,
  27 # Boston, MA, 02111-1307, USA.
  28 #
  29 
  30 from __future__ import print_function
  31 
  32 # Add local python path to the global path and import standard library modules...
  33 import os
  34 import sys;  sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), "..", "lib", "Python"))
  35 import time
  36 import re
  37 
  38 # PyMOL imports...
  39 try:
  40     import pymol
  41     # Finish launching PyMOL in  a command line mode for batch processing (-c)
  42     # along with the following options:  disable loading of pymolrc and plugins (-k);
  43     # suppress start up messages (-q)
  44     pymol.finish_launching(['pymol', '-ckq'])
  45 except ImportError as ErrMsg:
  46     sys.stderr.write("\nFailed to import PyMOL module/package: %s\n" % ErrMsg)
  47     sys.stderr.write("Check/update your PyMOL environment and try again.\n\n")
  48     sys.exit(1)
  49 
  50 # MayaChemTools imports...
  51 try:
  52     from docopt import docopt
  53     import MiscUtil
  54     import PyMOLUtil
  55 except ImportError as ErrMsg:
  56     sys.stderr.write("\nFailed to import MayaChemTools module/package: %s\n" % ErrMsg)
  57     sys.stderr.write("Check/update your MayaChemTools environment and try again.\n\n")
  58     sys.exit(1)
  59 
  60 ScriptName = os.path.basename(sys.argv[0])
  61 Options = {}
  62 OptionsInfo = {}
  63 
  64 def main():
  65     """Start execution of the script."""
  66     
  67     MiscUtil.PrintInfo("\n%s (PyMOL v%s; MayaChemTools v%s; %s): Starting...\n" % (ScriptName, pymol.cmd.get_version()[0], MiscUtil.GetMayaChemToolsVersion(), time.asctime()))
  68     
  69     (WallClockTime, ProcessorTime) = MiscUtil.GetWallClockAndProcessorTime()
  70     
  71     # Retrieve command line arguments and options...
  72     RetrieveOptions()
  73     
  74     # Process and validate command line arguments and options...
  75     ProcessOptions()
  76 
  77     # Perform actions required by the script...
  78     ExtractSelection()
  79     
  80     MiscUtil.PrintInfo("\n%s: Done...\n" % ScriptName)
  81     MiscUtil.PrintInfo("Total time: %s" % MiscUtil.GetFormattedElapsedTime(WallClockTime, ProcessorTime))
  82 
  83 def ExtractSelection():
  84     """Extract selection from input file and write it out."""
  85 
  86     MiscUtil.PrintInfo("\nGenerating output files...")
  87 
  88     # Load macromolecule from input file...
  89     MolName = OptionsInfo["InfileRoot"]
  90     pymol.cmd.load(OptionsInfo["Infile"], MolName)
  91     
  92     # Extract and write selection...
  93     ExtractAndWriteSelection(MolName)
  94     
  95     # Delete macromolecule...
  96     pymol.cmd.delete(MolName)
  97 
  98 def ExtractAndWriteSelection(MolName):
  99     """Extract selection from an input file  and write it out."""
 100 
 101     Outfile = OptionsInfo["Outfile"]
 102     MiscUtil.PrintInfo("\nGenerating output file %s..." % Outfile)
 103 
 104     # Setup selection...
 105     if OptionsInfo["SelectionAppend"]:
 106         MolSelection = "(%s and (%s))" % (MolName, OptionsInfo["Selection"])
 107     else:
 108         MolSelection = "(%s)" % (OptionsInfo["Selection"])
 109         
 110     MolSelectionName = OptionsInfo["SelectionName"]
 111 
 112     # Create selection object and write it out...
 113     MiscUtil.PrintInfo("Extracting selection: %s" % MolSelection)
 114     
 115     pymol.cmd.create(MolSelectionName, MolSelection)
 116     pymol.cmd.save(Outfile, MolSelectionName)
 117     pymol.cmd.delete(MolSelectionName)
 118     
 119     if not os.path.exists(Outfile):
 120         MiscUtil.PrintWarning("Failed to generate output file, %s..." % (Outfile))
 121 
 122 def ProcessOptions():
 123     """Process and validate command line arguments and options."""
 124     
 125     MiscUtil.PrintInfo("Processing options...")
 126     
 127     # Validate options...
 128     ValidateOptions()
 129 
 130     OptionsInfo["Infile"] = Options["--infile"]
 131     FileDir, FileName, FileExt = MiscUtil.ParseFileName(OptionsInfo["Infile"])
 132     OptionsInfo["InfileRoot"] = FileName
 133 
 134     OptionsInfo["Outfile"] = Options["--outfile"]
 135     
 136     OptionsInfo["Selection"] = Options["--selection"]
 137     OptionsInfo["SelectionName"] = "%s_Selection" % OptionsInfo["InfileRoot"] 
 138     
 139     OptionsInfo["SelectionAppend"] = True if re.match("^Yes$", Options["--selectionAppend"], re.I) else False
 140     
 141     OptionsInfo["Overwrite"] = Options["--overwrite"]
 142 
 143 def RetrieveOptions(): 
 144     """Retrieve command line arguments and options."""
 145     
 146     # Get options...
 147     global Options
 148     Options = docopt(_docoptUsage_)
 149 
 150     # Set current working directory to the specified directory...
 151     WorkingDir = Options["--workingdir"]
 152     if WorkingDir:
 153         os.chdir(WorkingDir)
 154     
 155     # Handle examples option...
 156     if "--examples" in Options and Options["--examples"]:
 157         MiscUtil.PrintInfo(MiscUtil.GetExamplesTextFromDocOptText(_docoptUsage_))
 158         sys.exit(0)
 159 
 160 def ValidateOptions():
 161     """Validate option values."""
 162 
 163     MiscUtil.ValidateOptionFilePath("-i, --infile", Options["--infile"])
 164     MiscUtil.ValidateOptionFileExt("-i, --infile", Options["--infile"], "pdb cif")
 165 
 166     MiscUtil.ValidateOptionFileExt("-o, --outfile", Options["--outfile"], "pdb cif")
 167     MiscUtil.ValidateOptionsOutputFileOverwrite("-o, --outfile", Options["--outfile"], "--overwrite", Options["--overwrite"])
 168     MiscUtil.ValidateOptionsDistinctFileNames("-i, --infile", Options["--infile"], "-o, --outfile", Options["--outfile"])
 169 
 170     MiscUtil.ValidateOptionTextValue("--selectionAppend", Options["--selectionAppend"], "yes no")
 171 
 172 # Setup a usage string for docopt...
 173 _docoptUsage_ = """
 174 PyMOLExtractSelection.py - Extract selection from a macromolecule
 175 
 176 Usage:
 177     PyMOLExtractSelection.py [--overwrite] [--selectionAppend <yes or no>]
 178                              [-w <dir>] -i <infile> -o <outfile> -s <selection>
 179     PyMOLExtractSelection.py -h | --help | -e | --examples
 180 
 181 Description:
 182     Extract data corresponding to a PyMOL selection specification from a
 183     macromolecule in an input file and write it out to an output file.
 184 
 185     The selection specification must be a valid PyMOL specification. No
 186     validation is performed.
 187 
 188     The supported input file format are:  PDB (.pdb) and CIF (.cif)
 189 
 190     The supported output file formats are:  PDB (.pdb) and CIF (.cif)
 191 
 192 Options:
 193     -e, --examples
 194         Print examples.
 195     -h, --help
 196         Print this help message.
 197     -i, --infile <infile>
 198         Input file name.
 199     -o, --outfile <infile>
 200         Output file name.
 201     -s, --selection <PyMOL SelectionSpec>
 202         Selection specification for extracting data from a macromolecule in an
 203         input file. The selection specification must be a valid PyMOL specification.
 204         No Validation is performed.
 205         
 206         The specified selection specification is optionally appended to PyMOL
 207         object name for input file.
 208     --selectionAppend <yes or no>  [default: yes]
 209         Append specified selection specification to  PyMOL object name for input
 210         file  before creating PyMOL object for a specified selection specification.
 211         The PyMOL object name for input file is <InfileRoot>.
 212         
 213         You may choose to explicitly specify PyMOL object name in the selection
 214         specification instead of automatically appending it to the selection.
 215     --overwrite
 216         Overwrite existing files.
 217     -w, --workingdir <dir>
 218         Location of working directory which defaults to the current directory.
 219 
 220 Examples:
 221     To extract all data corresponding to chain E in a macromolecule and write
 222     out to a PDB file, type:
 223 
 224         % PyMOLExtractSelection.py -i Sample3.cif -o Sample3Out.pdb -s "chain E" --ov
 225 
 226     To extract only polymer chain data for chains E and I in a macromolecule and
 227     write out to a PDB file, type:
 228 
 229         % PyMOLExtractSelection.py -i Sample3.cif -o Sample3Out.pdb
 230           -s "((chain E) or (chain I)) and polymer" --ov
 231 
 232     To extract only polymer chain data for chain E in a macromolecule and write
 233     out to a PDB file, type:
 234 
 235         % PyMOLExtractSelection.py -i Sample3.pdb -o Sample3Out.pdb
 236           -s "(chain E) and polymer" --ov
 237 
 238     To extract only polymer chain data for chain E in a macromolecule by explicitly
 239     ignoring non-polymer chain data and write out to a CIF file, type:
 240 
 241         % PyMOLExtractSelection.py -i Sample3.pdb -o Sample3Out.cif
 242           -s "(chain E) and (not organic) and (not solvent) and
 243           (not inorganic)" --ov
 244 
 245     To extract solvent data corresponding to chain E in a macromolecule and write
 246     out to a PDB file, type:
 247 
 248         % PyMOLExtractSelection.py -i Sample3.pdb -o Sample3Out.pdb
 249           -s "(chain E) and solvent" --ov
 250 
 251     To extract ligand data corresponding to chain E in a macromolecule and write
 252     out to a PDB file, type:
 253 
 254         % PyMOLExtractSelection.py -i Sample3.pdb -o Sample3Out.pdb
 255           -s "(chain E) and organic" --ov
 256 
 257     To extract binding pocket residues with 5.0 of ligand ID ADP in chain E and write
 258     out a PDB file, type:
 259 
 260         % PyMOLExtractSelection.py -i Sample3.pdb -o Sample3Out.pdb
 261            --selectionAppend no -s "(byresidue (Sample3 and chain E)
 262           within 5.0 of (Sample3 and chain E and organic and resn ADP))
 263           and polymer" --ov
 264 
 265 Author:
 266     Manish Sud(msud@san.rr.com)
 267 
 268 See also:
 269     PyMOLAlignChains.py, PyMOLSplitChainsAndLigands.py,
 270     PyMOLVisualizeMacromolecules.py
 271 
 272 Copyright:
 273     Copyright (C) 2024 Manish Sud. All rights reserved.
 274 
 275     The functionality available in this script is implemented using PyMOL, a
 276     molecular visualization system on an open source foundation originally
 277     developed by Warren DeLano.
 278 
 279     This file is part of MayaChemTools.
 280 
 281     MayaChemTools is free software; you can redistribute it and/or modify it under
 282     the terms of the GNU Lesser General Public License as published by the Free
 283     Software Foundation; either version 3 of the License, or (at your option) any
 284     later version.
 285 
 286 """
 287 
 288 if __name__ == "__main__":
 289     main()