1 #!/bin/env python 2 # 3 # File: PyMOLExtractSelection.py 4 # Author: Manish Sud <msud@san.rr.com> 5 # 6 # Copyright (C) 2026 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 import os 33 import sys 34 import time 35 import re 36 37 # PyMOL imports... 38 try: 39 import pymol 40 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 sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), "..", "lib", "Python")) 52 try: 53 from docopt import docopt 54 import MiscUtil 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 65 def main(): 66 """Start execution of the script.""" 67 68 MiscUtil.PrintInfo( 69 "\n%s (PyMOL v%s; MayaChemTools v%s; %s): Starting...\n" 70 % (ScriptName, pymol.cmd.get_version()[0], MiscUtil.GetMayaChemToolsVersion(), time.asctime()) 71 ) 72 73 (WallClockTime, ProcessorTime) = MiscUtil.GetWallClockAndProcessorTime() 74 75 # Retrieve command line arguments and options... 76 RetrieveOptions() 77 78 # Process and validate command line arguments and options... 79 ProcessOptions() 80 81 # Perform actions required by the script... 82 ExtractSelection() 83 84 MiscUtil.PrintInfo("\n%s: Done...\n" % ScriptName) 85 MiscUtil.PrintInfo("Total time: %s" % MiscUtil.GetFormattedElapsedTime(WallClockTime, ProcessorTime)) 86 87 88 def ExtractSelection(): 89 """Extract selection from input file and write it out.""" 90 91 MiscUtil.PrintInfo("\nGenerating output files...") 92 93 # Load macromolecule from input file... 94 MolName = OptionsInfo["InfileRoot"] 95 pymol.cmd.load(OptionsInfo["Infile"], MolName) 96 97 # Extract and write selection... 98 ExtractAndWriteSelection(MolName) 99 100 # Delete macromolecule... 101 pymol.cmd.delete(MolName) 102 103 104 def ExtractAndWriteSelection(MolName): 105 """Extract selection from an input file and write it out.""" 106 107 Outfile = OptionsInfo["Outfile"] 108 MiscUtil.PrintInfo("\nGenerating output file %s..." % Outfile) 109 110 # Setup selection... 111 if OptionsInfo["SelectionAppend"]: 112 MolSelection = "(%s and (%s))" % (MolName, OptionsInfo["Selection"]) 113 else: 114 MolSelection = "(%s)" % (OptionsInfo["Selection"]) 115 116 MolSelectionName = OptionsInfo["SelectionName"] 117 118 # Create selection object and write it out... 119 MiscUtil.PrintInfo("Extracting selection: %s" % MolSelection) 120 121 pymol.cmd.create(MolSelectionName, MolSelection) 122 pymol.cmd.save(Outfile, MolSelectionName) 123 pymol.cmd.delete(MolSelectionName) 124 125 if not os.path.exists(Outfile): 126 MiscUtil.PrintWarning("Failed to generate output file, %s..." % (Outfile)) 127 128 129 def ProcessOptions(): 130 """Process and validate command line arguments and options.""" 131 132 MiscUtil.PrintInfo("Processing options...") 133 134 # Validate options... 135 ValidateOptions() 136 137 OptionsInfo["Infile"] = Options["--infile"] 138 FileDir, FileName, FileExt = MiscUtil.ParseFileName(OptionsInfo["Infile"]) 139 OptionsInfo["InfileRoot"] = FileName 140 141 OptionsInfo["Outfile"] = Options["--outfile"] 142 143 OptionsInfo["Selection"] = Options["--selection"] 144 OptionsInfo["SelectionName"] = "%s_Selection" % OptionsInfo["InfileRoot"] 145 146 OptionsInfo["SelectionAppend"] = True if re.match("^Yes$", Options["--selectionAppend"], re.I) else False 147 148 OptionsInfo["Overwrite"] = Options["--overwrite"] 149 150 151 def RetrieveOptions(): 152 """Retrieve command line arguments and options.""" 153 154 # Get options... 155 global Options 156 Options = docopt(_docoptUsage_) 157 158 # Set current working directory to the specified directory... 159 WorkingDir = Options["--workingdir"] 160 if WorkingDir: 161 os.chdir(WorkingDir) 162 163 # Handle examples option... 164 if "--examples" in Options and Options["--examples"]: 165 MiscUtil.PrintInfo(MiscUtil.GetExamplesTextFromDocOptText(_docoptUsage_)) 166 sys.exit(0) 167 168 169 def ValidateOptions(): 170 """Validate option values.""" 171 172 MiscUtil.ValidateOptionFilePath("-i, --infile", Options["--infile"]) 173 MiscUtil.ValidateOptionFileExt("-i, --infile", Options["--infile"], "pdb cif") 174 175 MiscUtil.ValidateOptionFileExt("-o, --outfile", Options["--outfile"], "pdb cif") 176 MiscUtil.ValidateOptionsOutputFileOverwrite( 177 "-o, --outfile", Options["--outfile"], "--overwrite", Options["--overwrite"] 178 ) 179 MiscUtil.ValidateOptionsDistinctFileNames( 180 "-i, --infile", Options["--infile"], "-o, --outfile", Options["--outfile"] 181 ) 182 183 MiscUtil.ValidateOptionTextValue("--selectionAppend", Options["--selectionAppend"], "yes no") 184 185 186 # Setup a usage string for docopt... 187 _docoptUsage_ = """ 188 PyMOLExtractSelection.py - Extract selection from a macromolecule 189 190 Usage: 191 PyMOLExtractSelection.py [--overwrite] [--selectionAppend <yes or no>] 192 [-w <dir>] -i <infile> -o <outfile> -s <selection> 193 PyMOLExtractSelection.py -h | --help | -e | --examples 194 195 Description: 196 Extract data corresponding to a PyMOL selection specification from a 197 macromolecule in an input file and write it out to an output file. 198 199 The selection specification must be a valid PyMOL specification. No 200 validation is performed. 201 202 The supported input file format are: PDB (.pdb) and CIF (.cif) 203 204 The supported output file formats are: PDB (.pdb) and CIF (.cif) 205 206 Options: 207 -e, --examples 208 Print examples. 209 -h, --help 210 Print this help message. 211 -i, --infile <infile> 212 Input file name. 213 -o, --outfile <infile> 214 Output file name. 215 -s, --selection <PyMOL SelectionSpec> 216 Selection specification for extracting data from a macromolecule in an 217 input file. The selection specification must be a valid PyMOL specification. 218 No Validation is performed. 219 220 The specified selection specification is optionally appended to PyMOL 221 object name for input file. 222 --selectionAppend <yes or no> [default: yes] 223 Append specified selection specification to PyMOL object name for input 224 file before creating PyMOL object for a specified selection specification. 225 The PyMOL object name for input file is <InfileRoot>. 226 227 You may choose to explicitly specify PyMOL object name in the selection 228 specification instead of automatically appending it to the selection. 229 --overwrite 230 Overwrite existing files. 231 -w, --workingdir <dir> 232 Location of working directory which defaults to the current directory. 233 234 Examples: 235 To extract all data corresponding to chain E in a macromolecule and write 236 out to a PDB file, type: 237 238 % PyMOLExtractSelection.py -i Sample3.cif -o Sample3Out.pdb -s "chain E" --ov 239 240 To extract only polymer chain data for chains E and I in a macromolecule and 241 write out to a PDB file, type: 242 243 % PyMOLExtractSelection.py -i Sample3.cif -o Sample3Out.pdb 244 -s "((chain E) or (chain I)) and polymer" --ov 245 246 To extract only polymer chain data for chain E in a macromolecule and write 247 out to a PDB file, type: 248 249 % PyMOLExtractSelection.py -i Sample3.pdb -o Sample3Out.pdb 250 -s "(chain E) and polymer" --ov 251 252 To extract only polymer chain data for chain E in a macromolecule by explicitly 253 ignoring non-polymer chain data and write out to a CIF file, type: 254 255 % PyMOLExtractSelection.py -i Sample3.pdb -o Sample3Out.cif 256 -s "(chain E) and (not organic) and (not solvent) and 257 (not inorganic)" --ov 258 259 To extract solvent data corresponding to chain E in a macromolecule and write 260 out to a PDB file, type: 261 262 % PyMOLExtractSelection.py -i Sample3.pdb -o Sample3Out.pdb 263 -s "(chain E) and solvent" --ov 264 265 To extract ligand data corresponding to chain E in a macromolecule and write 266 out to a PDB file, type: 267 268 % PyMOLExtractSelection.py -i Sample3.pdb -o Sample3Out.pdb 269 -s "(chain E) and organic" --ov 270 271 To extract binding pocket residues with 5.0 of ligand ID ADP in chain E and write 272 out a PDB file, type: 273 274 % PyMOLExtractSelection.py -i Sample3.pdb -o Sample3Out.pdb 275 --selectionAppend no -s "(byresidue (Sample3 and chain E) 276 within 5.0 of (Sample3 and chain E and organic and resn ADP)) 277 and polymer" --ov 278 279 Author: 280 Manish Sud(msud@san.rr.com) 281 282 See also: 283 PyMOLAlignChains.py, PyMOLSplitChainsAndLigands.py, 284 PyMOLVisualizeMacromolecules.py 285 286 Copyright: 287 Copyright (C) 2026 Manish Sud. All rights reserved. 288 289 The functionality available in this script is implemented using PyMOL, a 290 molecular visualization system on an open source foundation originally 291 developed by Warren DeLano. 292 293 This file is part of MayaChemTools. 294 295 MayaChemTools is free software; you can redistribute it and/or modify it under 296 the terms of the GNU Lesser General Public License as published by the Free 297 Software Foundation; either version 3 of the License, or (at your option) any 298 later version. 299 300 """ 301 302 if __name__ == "__main__": 303 main()