├── .DS_Store ├── .gitignore ├── .readthedocs.yaml ├── LICENSE ├── README.md ├── docs ├── .DS_Store ├── docs │ ├── .DS_Store │ ├── img │ │ ├── .DS_Store │ │ ├── MC_diagram.png │ │ └── flowchart.png │ ├── index.md │ ├── input_parameters.md │ ├── installation.md │ ├── output.md │ └── run.md └── mkdocs.yml ├── examples ├── example_ini_files │ ├── adf_input.ini │ ├── gaussian_input.ini │ ├── mc_input.ini │ └── orca_input.ini └── example_runs │ ├── monte_carlo │ ├── MetalDock.log │ ├── data_set │ │ └── compound_1 │ │ │ ├── compound_1.pdbqt │ │ │ ├── compound_1_c.xyz │ │ │ └── protein_1.pdbqt │ ├── input.ini │ ├── metal_dock_optimize.dat │ ├── run.sh │ └── slurm-9807103.out │ ├── no_vacancy_coordination_sphere │ ├── ADF │ │ ├── 2bzh_B_HB1.xyz │ │ ├── input.ini │ │ └── run.sh │ ├── GAUSSIAN │ │ ├── 2bzh.pdb │ │ ├── 2bzh_B_HB1.xyz │ │ ├── input.ini │ │ └── run.sh │ └── ORCA │ │ ├── 2bzh.pdb │ │ ├── 2bzh_B_HB1.xyz │ │ ├── input.ini │ │ └── run.sh │ └── vacancy_coordination_sphere │ ├── ADF │ ├── 1jzi.pdb │ ├── 1jzi_D_REP.xyz │ ├── input.ini │ └── run.sh │ ├── GAUSSIAN │ ├── 1jzi.pdb │ ├── 1jzi_D_REP.xyz │ ├── input.ini │ └── run.sh │ └── ORCA │ ├── 1jzi.pdb │ ├── 1jzi_D_REP.xyz │ ├── input.ini │ └── run.sh ├── metaldock ├── pyproject.toml ├── setup.cfg └── src ├── .DS_Store ├── external ├── AutoDock │ ├── autodock4 │ └── autogrid4 └── AutoDockTools │ ├── AD4.1_bound.dat │ ├── AD4_parameters.dat │ ├── AutoDockBondClassifier.py │ ├── Conformation.py │ ├── GridParameters.py │ ├── LICENSE │ ├── MolKit │ ├── APBSParameters.py │ ├── GapFinder.py │ ├── LICENSE │ ├── MolecularDescriptor.py │ ├── PDBdict.py │ ├── PDBresidueNames.py │ ├── PROSS.py │ ├── RELNOTES │ ├── WaterBuilder.py │ ├── __init__.py │ ├── amberPrmTop.py │ ├── bondClassifier.py │ ├── bondSelector.py │ ├── chargeCalculator.py │ ├── chargeMass.py │ ├── data │ │ ├── CVS │ │ │ ├── Entries │ │ │ ├── Repository │ │ │ ├── Root │ │ │ └── Tag │ │ ├── __init__.py │ │ ├── __init__.py.bak │ │ ├── all.in │ │ ├── all_amino94.in │ │ ├── all_amino94_dat.py │ │ ├── all_aminoct94.in │ │ ├── all_aminoct94_dat.py │ │ ├── all_aminont94.in │ │ ├── all_aminont94_dat.py │ │ ├── all_dat.py │ │ ├── all_nuc94.in │ │ ├── all_nuc94_dat.py │ │ ├── allct.in │ │ ├── allct_dat.py │ │ ├── allnt.in │ │ ├── allnt_dat.py │ │ ├── build_all_in.py │ │ ├── build_all_in.py.bak │ │ ├── nh2e.in │ │ ├── nh2e_dat.py │ │ ├── opls_nacl.in │ │ ├── opls_nacl_dat.py │ │ ├── opls_uni.in │ │ ├── opls_uni_dat.py │ │ ├── opls_unict.in │ │ ├── opls_unict_dat.py │ │ ├── opls_unint.in │ │ ├── opls_unint_dat.py │ │ ├── parm94.dat │ │ ├── qkollua.py │ │ ├── rotamer.def │ │ ├── uni_dat.py │ │ ├── unict_dat.py │ │ └── unint_dat.py │ ├── distanceSelector.py │ ├── genPdbParser.py │ ├── getsecondarystructure.py │ ├── groParser.py │ ├── hydrogenBondBuilder.py │ ├── hydrogenBuilder.py │ ├── interactionDescriptor.py │ ├── introduction.py │ ├── listSet.py │ ├── mmcifParser.py │ ├── mmcifWriter.py │ ├── mol2Parser.py │ ├── molecule.py │ ├── moleculeParser.py │ ├── moleculeWriter.py │ ├── oxtBuilder.py │ ├── parm94_dat.py │ ├── pdbParser.py │ ├── pdbWriter.py │ ├── pqrWriter.py │ ├── protein.py │ ├── radii_patterns.py │ ├── rotamerLib.py │ ├── sdfParser.py │ ├── sequence.py │ ├── sets.py │ ├── stringSelector.py │ ├── torTree.py │ ├── trajParser.py │ ├── tree.py │ └── waterBuilder.py │ ├── MoleculePreparation.py │ ├── PyBabel │ ├── CVS │ │ ├── Entries │ │ ├── Entries.Log │ │ ├── Repository │ │ ├── Root │ │ └── Tag │ ├── LICENSE │ ├── RELNOTES │ ├── __init__.py │ ├── addh.py │ ├── aromatic.py │ ├── atomTypes.py │ ├── babelAtomTypes.py │ ├── babelElements.py │ ├── bo.py │ ├── cycle.py │ ├── gasteiger.py │ ├── source.list │ ├── tools.py │ └── util.py │ ├── ResultParser.py │ ├── __init__.py │ ├── atomTypeTools.py │ ├── cluster.py │ ├── energyConstants.py │ ├── mglutil │ ├── math │ │ ├── CVS │ │ │ ├── Entries │ │ │ ├── Entries.Log │ │ │ ├── Repository │ │ │ ├── Root │ │ │ └── Tag │ │ ├── TensorModule.py │ │ ├── VectorModule.py │ │ ├── __init__.py │ │ ├── crystal.py │ │ ├── gridDescriptor.py │ │ ├── julie12019854k.rot │ │ ├── kinematics.py │ │ ├── kinematicstest.py │ │ ├── kmeansClustering.py │ │ ├── munkres.py │ │ ├── munkresLICENSE │ │ ├── ncoords.py │ │ ├── ncoordstest.py │ │ ├── rigidFit.py │ │ ├── rmsd.py │ │ ├── rmsdtest.py │ │ ├── rotax.py │ │ ├── statetocoords.py │ │ ├── statetocoordstest.py │ │ ├── stats.py │ │ ├── torsion.py │ │ ├── transformation.py │ │ ├── transformationtest.py │ │ └── usr.py │ └── util │ │ ├── CVS │ │ ├── Entries │ │ ├── Entries.Log │ │ ├── Repository │ │ ├── Root │ │ └── Tag │ │ ├── __init__.py │ │ ├── callback.py │ │ ├── colorUtil.py │ │ ├── defaultPalettes.py │ │ ├── idleUtil.py │ │ ├── misc.py │ │ ├── packageFilePath.py │ │ ├── parser.py │ │ ├── qhullUtils.py │ │ ├── recentFiles.py │ │ ├── relpath.py │ │ ├── repeatPrinter.py │ │ ├── tree.py │ │ └── uniq.py │ ├── prepare_gpf4.py │ ├── prepare_receptor4.py │ └── sol_par.py └── metal_dock ├── .gitignore ├── __init__.py ├── adf_engine.py ├── calculate_rmsd.py ├── cm5pars.json ├── docking.py ├── environment_variables.py ├── gaussian_engine.py ├── logger.py ├── main.py ├── metal_complex.py ├── metal_dock.dat ├── monte_carlo.py ├── orca_engine.py ├── parser_metal_dock.py ├── protein.py └── xyz2graph.py /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MatthijsHak/MetalDock/73a52ccf1bd1a8d199f80405ee9da70135c7cda6/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | MetalDocs 2 | .readthedocs.yaml 3 | dist 4 | *.pyc 5 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # Required 2 | version: 2 3 | 4 | mkdocs: 5 | configuration: docs/mkdocs.yml 6 | fail_on_warning: false 7 | 8 | build: 9 | os: ubuntu-22.04 10 | tools: 11 | python: "3.8" 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 MatthijsHak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # MetalDock 3 | 4 | MetalDock is a versatile open-source software docking tool designed to facilitate the docking of metal-organic complexes for various transtions metals with proteins, DNA, or other biomolecules. For detailed instructions on how to utilize MetalDock, we refer you to our [documentation](https://metaldock.readthedocs.io/en/latest/) page. 5 | 6 | # Citation 7 | 8 | If you decide to use MetalDock for any project, please cite the following paper: 9 | 10 | [https://doi.org/10.1021/acs.jcim.3c01582](https://doi.org/10.1021/acs.jcim.3c01582) 11 | -------------------------------------------------------------------------------- /docs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MatthijsHak/MetalDock/73a52ccf1bd1a8d199f80405ee9da70135c7cda6/docs/.DS_Store -------------------------------------------------------------------------------- /docs/docs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MatthijsHak/MetalDock/73a52ccf1bd1a8d199f80405ee9da70135c7cda6/docs/docs/.DS_Store -------------------------------------------------------------------------------- /docs/docs/img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MatthijsHak/MetalDock/73a52ccf1bd1a8d199f80405ee9da70135c7cda6/docs/docs/img/.DS_Store -------------------------------------------------------------------------------- /docs/docs/img/MC_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MatthijsHak/MetalDock/73a52ccf1bd1a8d199f80405ee9da70135c7cda6/docs/docs/img/MC_diagram.png -------------------------------------------------------------------------------- /docs/docs/img/flowchart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MatthijsHak/MetalDock/73a52ccf1bd1a8d199f80405ee9da70135c7cda6/docs/docs/img/flowchart.png -------------------------------------------------------------------------------- /docs/docs/index.md: -------------------------------------------------------------------------------- 1 | # Welcome to MetalDock Documentation 2 | 3 | Welcome to the official documentation for MetalDock. 4 | 5 | ## What is MetalDock? 6 | 7 | MetalDock is a Python-based tool designed for the docking of metal-organic compounds to proteins, DNA, or other biomolecules. Our program offers several metals as atom types and streamlines the rest of the docking process, automating key steps to save you time and effort. 8 | 9 | ## Getting Started 10 | 11 | If you're new to MetalDock, start with our [Installation](installation.md) chapter to set up the program on your system. Once installed, head over to our [Run MetalDock](run.md) for step-by-step instructions on running docking procedures and how to optimize your own parameters with the Monte Carlo optmisation scheme. 12 | 13 | ## Documentation Sections 14 | 15 | - [Installation](installation.md): Detailed installation instructions to get you up and running. 16 | - [Run MetalDock](run.md): tutorial and examples on using MetalDock for molecular docking. 17 | - [Input Parameters](input_parameters.md): Explore the various parameters you can customize for your docking experiments. 18 | - [Output](output.md): Understand the output generated by MetalDock. 19 | 20 | 21 | ## Citation 22 | 23 | If you use MetalDock for any project, please cite the following paper: 24 | 25 | [https://doi.org/10.1021/acs.jcim.3c01582](https://doi.org/10.1021/acs.jcim.3c01582) 26 | 27 | ## Problems 28 | 29 | Please use our GitHub issues [page](https://github.com/MatthijsHak/MetalDock/issues) if you run into any problems. 30 | -------------------------------------------------------------------------------- /docs/docs/installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | To install MetalDock correctly, please follow the instructions below: 4 | 5 | ## Step 1: Create Conda Environment 6 | 7 | First, make sure you have Miniconda or Anaconda installed. If not, you can find installation instructions at [Miniconda](https://docs.conda.io/en/latest/miniconda.html). 8 | 9 | Once you have Conda installed, create a new Conda environment named "MetalDock" and use Python 3.8: 10 | 11 | ```bash 12 | conda create -n MetalDock python=3.8 13 | ``` 14 | 15 | Activate the "MetalDock" environment: 16 | 17 | ```bash 18 | conda activate MetalDock 19 | ``` 20 | 21 | ## Step 2: Install Required Packages 22 | 23 | Next, install several required packages using Conda and Pip: 24 | 25 | ```bash 26 | conda install -c conda-forge openbabel 27 | ``` 28 | 29 | ```bash 30 | pip install ase==3.22.1 networkx numpy pandas pdb2pqr plams typing_extensions 31 | ``` 32 | 33 | ## Step 3: Clone MetalDock repository 34 | 35 | Clone the MetalDock respository to your desired location. 36 | 37 | ``` bash 38 | git clone https://github.com/MatthijsHak/MetalDock 39 | ``` 40 | 41 | ## Step 4: Setup QM environment variables 42 | 43 | MetalDock can run on three different quantum chemistry software packages: 44 | ### ADF 45 | To run ADF as QM engine the following environment variables need to be exported: 46 | ``` bash 47 | export AMSHOME=/full/path/to/ams/ams2022 48 | export AMSBIN=$AMSHOME/bin 49 | export AMSRESOURCES=$AMSHOME/atomicdata 50 | export SCMLICENSE=$AMSHOME/license.txt 51 | ``` 52 | 53 | Relativistic effects with ZORA. For more infromation see [SCM](https://www.scm.com/doc/ADF/index.html) site. 54 | 55 | ### Gaussian 56 | To run Gaussian as QM engine the following environment variables need to be exported. 57 | ``` bash 58 | export g16root=/full/path/to/gaussian/g16 59 | ``` 60 | 61 | Relativistic effects with DKH. For more information see [Gaussian](https://gaussian.com/) site. 62 | 63 | ### ORCA (free) 64 | Currently, the latest ORCA 6.0.0 version is not supported, install ORCA 5.0.4 or lower to use MetalDock. To run ORCA as QM engine with correct parralelization the full path to the orca binary has to be exported with the following command: 65 | ``` bash 66 | export ASE_ORCA_COMMAND='/full/path/to/orca/orca PREFIX.inp > PREFIX.out' 67 | ``` 68 | 69 | Relativistic effects can be selected with input. For more infromation see [ORCA](https://www.orcasoftware.de/tutorials_orca/index.html) site. 70 | 71 | 72 | ## Step 5: Add MetalDock to PATH 73 | 74 | If you want to use MetalDock conventiely from any directory, you can add its executable to your PATH. Replace /user/directory/MetalDock with the actual path to your MetalDock installation directory: 75 | 76 | ```bash 77 | export PATH=$PATH:/user/defined/path/MetalDock 78 | ``` 79 | 80 | This completes the installation process for MetalDock. You can now run metaldock by: 81 | 82 | ``` 83 | metaldock -i input.ini 84 | ``` 85 | 86 | -------------------------------------------------------------------------------- /docs/docs/output.md: -------------------------------------------------------------------------------- 1 | # Output in MetalDock 2 | 3 | MetalDock generates a dedicated directory named "output," which contains four distinct subdirectories, each serving a specific purpose in the docking process. 4 | 5 | ## 1. file_prep 6 | 7 | The "file_prep" directory plays a crucial role in preparing the necessary files for your docking experiments. Within this directory, MetalDock performs various tasks, including protonation of proteins and other essential file modifications to ensure accurate docking. 8 | 9 | ## 2. QM (Quantum Mechanical Calculation) 10 | 11 | Within the "QM" directory, MetalDock carries out Quantum Mechanical (QM) calculations, depending on your chosen settings. For each calculation, a separate subdirectory is created. This subdirectory houses either a geometry optimization or a single-point calculation. It is important to note that for cases where system convergence becomes an issue, a detailed examination of the subdirectory outputs can help in troubleshooting any problems that may arise. 12 | 13 | ## 3. docking 14 | 15 | The "docking" directory is where the core docking process takes place. MetalDock performs the entire docking procedure here, providing all the necessary files required by the AutoDock engine. For a more detailed insight into the docking process, you can access the ".dlg" file, which contains comprehensive information about the docking run. 16 | 17 | ## 4. results 18 | 19 | The "results" directory holds the output of the docking procedure. It presents the obtained poses in two file formats: ".pdbqt" and ".xyz." AutoDock generates the poses without non-polar hydrogens, so these are later on added and their position optimized with GFNxTB. 20 | 21 | The organization of the "output" directory ensures that you have easy access to all the essential files and results generated during the docking process, facilitating further analysis and exploration. 22 | -------------------------------------------------------------------------------- /docs/docs/run.md: -------------------------------------------------------------------------------- 1 | # Run MetalDock 2 | 3 | MetalDock is a Python program that performs molecular docking of metal-organic compounds. It uses a configuration file (**'.ini'**) to set various parameters for the docking procedure. 4 | 5 | To dock organometallic compounds, follow these simple steps: 6 | 7 | 1. Prepare an XYZ file of the compound you want to dock. 8 | 2. Prepare a PDB file of the protein, DNA, or biomolecule you want to interact with. 9 | 3. Create an input file with the desired parameters. You can find examples in the **'input_examples'** directory of the GitHub repository. 10 | 11 | ## How to run MetalDock docking procedure? 12 | You can run MetalDock with a single command. Simply provide the path to your input configuration file (e.g., input.ini) as shown below: 13 | 14 | ```bash 15 | metaldock -i input.ini -m dock 16 | ``` 17 | 18 | For a detailed description of the output directories and files please see the [output](output.md) chapter. 19 | 20 | ## What basis set and functional should I use? 21 | Choosing the correct settings for the quantum mechanical calculation can be tricky. Luckily, there have been numerous reviews on this subject that can help you with choosing the correct settings for your system. I would like to recommend the following two papers, for the less experienced quantum chemistry users: 22 | 23 | [Best-Practice DFT Protocols for Basic Molecular Computational Chemistry](https://onlinelibrary.wiley.com/doi/full/10.1002/ange.202205735) 24 | 25 | [Which functional should I choose?](https://www.chem.uci.edu/~kieron/dft/pubs/RCFB08.pdf) 26 | 27 | ## Docking workflow 28 | A workflow for the docking procedure is schematically given below. 29 | 30 | ![docking_flowchart](img/flowchart.png) 31 | 32 | ## How to run Monte Carlo Optimisation scheme? 33 | 34 | This protocol describes the steps to prepare input files for Monte Carlo parameter optimization after running the MetalDock protocol for each compound in your dataset. 35 | 36 | ### Prerequisites 37 | - MetalDock installed and configured 38 | - A dataset of compounds to be processed 39 | - Completed MetalDock runs for each compound 40 | 41 | ### Step-by-Step Instructions 42 | 43 | #### 1. Set Up the Run Directory & Parameter File 44 | Create a directory where you are going to run the Monte Carlo optimization protocol in. 45 | 46 | ```bash 47 | mc 48 | cd mc 49 | ``` 50 | 51 | Copy to this folder from the /MetalDock/src/metal_dock/metal_dock.dat to the mc directory and name it metal_dock_optimize.dat. 52 | 53 | Add at the bottom of the file the following line: 54 | 55 | atom_par M Rii 0.010 Vol -0.00110 0.0 0.0 2 -1 -1 4 # Non H-bonding 56 | 57 | * Replace M with the metal symbol of the new metal atom that you are going to optimize 58 | * Replace Rii with the sum of vdW radii of two like atoms (in Angstrom) 59 | * Replace Vol with the atomic solvation volume (in Angstrom^3) 60 | 61 | Use this parameter file as well for the next step in creating the dataset files. If you do not do this you will receive errors that the atom type is not found. 62 | 63 | #### 2. Set Up the Dataset Directory 64 | Create a dataset directory in the mc directory to store your dataset: 65 | 66 | ```bash 67 | mkdir data_set 68 | cd data_set 69 | ``` 70 | 71 | #### 3. Prepare Each Compound 72 | For each compound, follow these steps: 73 | 74 | 1. Create a directory for the compound: 75 | 76 | ```bash 77 | mkdir compound_1 78 | ``` 79 | 80 | 3. Copy and rename the required files from the MetalDock output: 81 | - **Ligand file** 82 | 83 | ```bash 84 | cp path/to/MetalDock/output/docking/ligand.pdbqt compound_1/compound_1.pdbqt 85 | ``` 86 | 87 | - **Protein file** 88 | 89 | ```bash 90 | cp path/to/MetalDock/output/docking/protein.pdbqt compound_1/protein_1.pdbqt 91 | ``` 92 | 93 | - **XYZ coordinate file** 94 | 95 | ```bash 96 | cp path/to/MetalDock/output/file_prep/ligand_c.xyz compound_1/compound_1_c.xyz 97 | ``` 98 | 99 | > Replace `path/to/MetalDock/` with the actual directory where MetalDock output files are stored. 100 | 101 | #### 4. Repeat for All Compounds 102 | Repeat the above steps for each compound in your dataset, renaming directories and files accordingly (e.g., `compound_2`, `compound_3`, etc.). 103 | 104 | #### 5. Create input.ini file 105 | Create a monte_carlo.ini file in the mc directory. Adjust in the monte_carlo.ini file the path and set it correctly to metal_dock_optimize.dat 106 | 107 | ``` 108 | [MC] 109 | mc_steps = 100 110 | parameter_file = metal_dock_optimize.dat 111 | ``` 112 | 113 | #### 6. Run the Monte Carlo optimization 114 | Run the following command to start the optimization. 115 | 116 | ```bash 117 | metaldock -i monte_carlo.ini -m mc 118 | ``` 119 | 120 | #### 7. Schematic overview Monte Carlo optimization 121 | Here's an schematic overview of the Monte Carlo optimisation procedure: 122 | 123 | ![monte_carlo)](img/MC_diagram.png) 124 | 125 | Each parameter is sequentially sampled from an equiprobable distribution. All complexes in the dataset are then docked and the average RMSD (Root Mean Square Deviation) is calculated. If the RMSD is lower than in the previous iteration, the parameter is accepted; otherwise, there is a probability of acceptance. 126 | 127 | For more details, see the following paper. 128 | -------------------------------------------------------------------------------- /docs/mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: MetalDock 2 | site_url: https://metal_dock_docs.com/ 3 | 4 | nav: 5 | - Home: index.md 6 | - Installation: installation.md 7 | - Run MetalDock: run.md 8 | - Input Parameters: input_parameters.md 9 | - Output: output.md 10 | theme: readthedocs 11 | -------------------------------------------------------------------------------- /examples/example_ini_files/adf_input.ini: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | metal_symbol = Ru 3 | method = dock 4 | ncpu = 1 5 | 6 | [PROTEIN] 7 | pdb_file = protein.pdb 8 | pH = 7.5 9 | clean_pdb = True 10 | 11 | [QM] 12 | engine = ADF 13 | basis_set = TZP 14 | functional_type = Hybrid 15 | functional = B3LYP 16 | dispersion = GRIMME3 BJDAMP 17 | solvent = water 18 | 19 | [METAL_COMPLEX] 20 | geom_opt = True 21 | xyz_file = 2bzh_B_HB1.xyz 22 | charge = 0 23 | spin = 0 24 | vacant_site = False 25 | 26 | [DOCKING] 27 | ga_dock = True 28 | dock_x = 10 29 | dock_y = 10 30 | dock_z = 10 31 | box_size = 20 32 | random_pos = True 33 | num_poses = 10 34 | -------------------------------------------------------------------------------- /examples/example_ini_files/gaussian_input.ini: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | metal_symbol = Ru 3 | method = dock 4 | ncpu = 1 5 | 6 | [PROTEIN] 7 | pdb_file = protein.pdb 8 | pH = 7.5 9 | clean_pdb = True 10 | 11 | [QM] 12 | engine = GAUSSIAN 13 | basis_set = def2TZVP 14 | functional = B3LYP 15 | dispersion = GD3BJ 16 | solvent = water 17 | 18 | [METAL_COMPLEX] 19 | geom_opt = True 20 | xyz_file = organometallic_compound.xyz 21 | charge = 2 22 | spin = 0 23 | vacant_site = True 24 | 25 | [DOCKING] 26 | ga_dock = True 27 | dock_x = 10 28 | dock_y = 10 29 | dock_z = 10 30 | box_size = 20 31 | random_pos = True 32 | num_poses = 10 33 | -------------------------------------------------------------------------------- /examples/example_ini_files/mc_input.ini: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | metal_symbol = Re 3 | method = dock 4 | ncpu = 16 5 | 6 | [MC] 7 | mc_steps = 100 8 | parameter_file = metal_dock.dat 9 | 10 | [DOCKING] 11 | rmsd = True 12 | box_size = 20 13 | random_pos = True 14 | 15 | num_poses = 1 16 | ga_dock = True 17 | ga_dock_pop_size = 200 18 | ga_dock_num_evals = 2500000 19 | ga_dock_num_generations = 30000 20 | ga_dock_elitism = 2 21 | ga_dock_mutation_rate = 0.2 22 | ga_dock_crossover_rate = 0.80 23 | ga_dock_window_size = 20 24 | -------------------------------------------------------------------------------- /examples/example_ini_files/orca_input.ini: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | metal_symbol = Ru 3 | method = dock 4 | ncpu = 1 5 | 6 | [PROTEIN] 7 | pdb_file = protein_name.pdb 8 | pH = 7.5 9 | clean_pdb = True 10 | 11 | [QM] 12 | engine = ORCA 13 | orcasimpleinput = B3LYP def2-TZVP 14 | orcablocks = %basis newECP Ru "def2-SD" end end 15 | 16 | [METAL_COMPLEX] 17 | geom_opt = True 18 | xyz_file = organometallic_compound.xyz 19 | charge = 2 20 | spin = 0 21 | vacant_site = True 22 | 23 | [DOCKING] 24 | ga_dock = True 25 | dock_x = 10 26 | dock_y = 10 27 | dock_z = 10 28 | box_size = 20 29 | random_pos = True 30 | num_poses = 10 31 | -------------------------------------------------------------------------------- /examples/example_runs/monte_carlo/MetalDock.log: -------------------------------------------------------------------------------- 1 | 2025-02-07 11:02:19,055 - MetalDock - INFO - #==============================================================================# 2 | 2025-02-07 11:02:19,055 - MetalDock - INFO - STARTING METALDOCK 3 | 2025-02-07 11:02:19,055 - MetalDock - INFO - #==============================================================================# 4 | 5 | 2025-02-07 11:02:19,060 - MetalDock - INFO - #==============================================================================# 6 | 2025-02-07 11:02:19,060 - MetalDock - INFO - STARTING MONTE CARLO OPTIMIZATION 7 | 2025-02-07 11:02:19,060 - MetalDock - INFO - #==============================================================================# 8 | 2025-02-07 11:02:29,164 - MetalDock - INFO - #------------------------------------# 9 | 2025-02-07 11:02:29,164 - MetalDock - INFO - compound_1 10 | 2025-02-07 11:02:29,164 - MetalDock - INFO - #------------------------------------# 11 | 2025-02-07 11:02:29,164 - MetalDock - INFO - RMSD for Conformation 1 = 5.5064 12 | 2025-02-07 11:02:29,164 - MetalDock - INFO - Average RMSD = 5.5064 13 | 2025-02-07 11:02:29,164 - MetalDock - INFO - Standard Deviation RMSD = 0.0000 14 | 2025-02-07 11:02:29,165 - MetalDock - INFO - Variance RMSD = 0.0000 15 | 16 | 2025-02-07 11:02:29,165 - MetalDock - INFO - #==============================================================================# 17 | 2025-02-07 11:02:29,165 - MetalDock - INFO - MONTE CARLO STEP 1 18 | 2025-02-07 11:02:29,165 - MetalDock - INFO - #==============================================================================# 19 | 2025-02-07 11:02:39,225 - MetalDock - INFO - #------------------------------------# 20 | 2025-02-07 11:02:39,226 - MetalDock - INFO - compound_1 21 | 2025-02-07 11:02:39,226 - MetalDock - INFO - #------------------------------------# 22 | 2025-02-07 11:02:39,226 - MetalDock - INFO - RMSD for Conformation 1 = 5.5086 23 | 2025-02-07 11:02:39,226 - MetalDock - INFO - Average RMSD = 5.5086 24 | 2025-02-07 11:02:39,226 - MetalDock - INFO - Standard Deviation RMSD = 0.0000 25 | 2025-02-07 11:02:39,226 - MetalDock - INFO - Variance RMSD = 0.0000 26 | 27 | 2025-02-07 11:02:39,226 - MetalDock - INFO - RMSD: 5.50863 28 | 2025-02-07 11:02:39,226 - MetalDock - INFO - PARAMETER SET: [1.6421080237217942, 2, 2, 2] 29 | 30 | 2025-02-07 11:02:39,226 - MetalDock - INFO - BEST RMSD: 5.50639 31 | 2025-02-07 11:02:39,226 - MetalDock - INFO - BEST PARAMETER SET: [2, 2, 2, 2] 32 | 33 | 2025-02-07 11:02:39,226 - MetalDock - INFO - ACCEPTED WITH HIGHER RMSD 34 | 2025-02-07 11:02:39,226 - MetalDock - INFO - NEW PARAMETER SET: [1.6421080237217942, 2, 2, 2] 35 | 36 | 2025-02-07 11:02:39,227 - MetalDock - INFO - #==============================================================================# 37 | 2025-02-07 11:02:39,227 - MetalDock - INFO - MONTE CARLO STEP 2 38 | 2025-02-07 11:02:39,227 - MetalDock - INFO - #==============================================================================# 39 | 2025-02-07 11:02:49,266 - MetalDock - INFO - #------------------------------------# 40 | 2025-02-07 11:02:49,271 - MetalDock - INFO - compound_1 41 | 2025-02-07 11:02:49,271 - MetalDock - INFO - #------------------------------------# 42 | 2025-02-07 11:02:49,271 - MetalDock - INFO - RMSD for Conformation 1 = 5.6327 43 | 2025-02-07 11:02:49,271 - MetalDock - INFO - Average RMSD = 5.6327 44 | 2025-02-07 11:02:49,271 - MetalDock - INFO - Standard Deviation RMSD = 0.0000 45 | 2025-02-07 11:02:49,271 - MetalDock - INFO - Variance RMSD = 0.0000 46 | 47 | 2025-02-07 11:02:49,272 - MetalDock - INFO - RMSD: 5.63274 48 | 2025-02-07 11:02:49,272 - MetalDock - INFO - PARAMETER SET: [1.6421080237217942, 4.7386795094458485, 2, 2] 49 | 50 | 2025-02-07 11:02:49,272 - MetalDock - INFO - BEST RMSD: 5.50863 51 | 2025-02-07 11:02:49,272 - MetalDock - INFO - BEST PARAMETER SET: [1.6421080237217942, 2, 2, 2] 52 | 53 | 2025-02-07 11:02:49,272 - MetalDock - INFO - ACCEPTED WITH HIGHER RMSD 54 | 2025-02-07 11:02:49,272 - MetalDock - INFO - NEW PARAMETER SET: [1.6421080237217942, 4.7386795094458485, 2, 2] 55 | 56 | 2025-02-07 11:02:49,272 - MetalDock - INFO - #==============================================================================# 57 | 2025-02-07 11:02:49,272 - MetalDock - INFO - MONTE CARLO STEP 3 58 | 2025-02-07 11:02:49,272 - MetalDock - INFO - #==============================================================================# 59 | 2025-02-07 11:02:59,365 - MetalDock - INFO - #------------------------------------# 60 | 2025-02-07 11:02:59,365 - MetalDock - INFO - compound_1 61 | 2025-02-07 11:02:59,365 - MetalDock - INFO - #------------------------------------# 62 | 2025-02-07 11:02:59,365 - MetalDock - INFO - RMSD for Conformation 1 = 5.6658 63 | 2025-02-07 11:02:59,365 - MetalDock - INFO - Average RMSD = 5.6658 64 | 2025-02-07 11:02:59,365 - MetalDock - INFO - Standard Deviation RMSD = 0.0000 65 | 2025-02-07 11:02:59,365 - MetalDock - INFO - Variance RMSD = 0.0000 66 | 67 | 2025-02-07 11:02:59,366 - MetalDock - INFO - RMSD: 5.66583 68 | 2025-02-07 11:02:59,366 - MetalDock - INFO - PARAMETER SET: [1.6421080237217942, 4.7386795094458485, 4.966508905994022, 2] 69 | 70 | 2025-02-07 11:02:59,366 - MetalDock - INFO - BEST RMSD: 5.63274 71 | 2025-02-07 11:02:59,366 - MetalDock - INFO - BEST PARAMETER SET: [1.6421080237217942, 4.7386795094458485, 2, 2] 72 | 73 | 2025-02-07 11:02:59,366 - MetalDock - INFO - ACCEPTED WITH HIGHER RMSD 74 | 2025-02-07 11:02:59,366 - MetalDock - INFO - NEW PARAMETER SET: [1.6421080237217942, 4.7386795094458485, 4.966508905994022, 2] 75 | 76 | 2025-02-07 11:02:59,366 - MetalDock - INFO - #==============================================================================# 77 | 2025-02-07 11:02:59,366 - MetalDock - INFO - MONTE CARLO STEP 4 78 | 2025-02-07 11:02:59,366 - MetalDock - INFO - #==============================================================================# 79 | -------------------------------------------------------------------------------- /examples/example_runs/monte_carlo/data_set/compound_1/compound_1.pdbqt: -------------------------------------------------------------------------------- 1 | ROOT 2 | ATOM 1 Re LIG A 1 1.650 -7.803 27.176 0.00 0.00 0.740 Re 3 | ATOM 2 H LIG A 1 1.423 -6.872 26.891 0.00 0.00 0.000 DD 4 | ATOM 3 C LIG A 1 2.539 -9.348 27.972 0.00 0.00 0.100 C 5 | ATOM 4 O LIG A 1 3.052 -10.277 28.423 0.00 0.00 -0.149 OA 6 | ATOM 5 C LIG A 1 3.353 -7.239 26.462 0.00 0.00 0.056 C 7 | ATOM 6 O LIG A 1 4.370 -6.908 26.065 0.00 0.00 -0.160 OA 8 | ATOM 7 C LIG A 1 2.110 -6.786 28.770 0.00 0.00 0.072 C 9 | ATOM 8 O LIG A 1 2.349 -6.191 29.681 0.00 0.00 -0.150 OA 10 | ATOM 9 N LIG A 1 -0.345 -8.421 27.733 0.00 0.00 -0.361 N 11 | ATOM 10 C LIG A 1 -0.983 -8.127 28.874 0.00 0.00 0.083 A 12 | ATOM 11 C LIG A 1 -2.271 -8.593 29.156 0.00 0.00 -0.067 A 13 | ATOM 12 C LIG A 1 -2.917 -9.345 28.249 0.00 0.00 -0.040 C 14 | ATOM 13 C LIG A 1 -2.294 -9.687 27.015 0.00 0.00 0.020 A 15 | ATOM 14 C LIG A 1 -0.992 -9.184 26.803 0.00 0.00 0.125 A 16 | ATOM 15 C LIG A 1 -0.292 -9.471 25.584 0.00 0.00 0.124 A 17 | ATOM 16 N LIG A 1 0.976 -8.950 25.457 0.00 0.00 -0.355 N 18 | ATOM 17 C LIG A 1 1.629 -9.208 24.316 0.00 0.00 0.082 A 19 | ATOM 18 C LIG A 1 1.088 -9.985 23.277 0.00 0.00 -0.064 A 20 | ATOM 19 C LIG A 1 -0.170 -10.491 23.426 0.00 0.00 -0.042 C 21 | ATOM 20 C LIG A 1 -0.897 -10.258 24.588 0.00 0.00 0.015 A 22 | ATOM 21 C LIG A 1 -2.228 -10.756 24.823 0.00 0.00 -0.069 C 23 | ATOM 22 C LIG A 1 -2.885 -10.490 25.972 0.00 0.00 -0.071 C 24 | ENDROOT 25 | -------------------------------------------------------------------------------- /examples/example_runs/monte_carlo/data_set/compound_1/compound_1_c.xyz: -------------------------------------------------------------------------------- 1 | 29 2 | REP 3 | O 3.05200 -10.27700 28.42300 4 | C 2.53900 -9.34800 27.97200 5 | Re 1.65000 -7.80300 27.17600 6 | C 3.35300 -7.23900 26.46200 7 | C 2.11000 -6.78600 28.77000 8 | N -0.34500 -8.42100 27.73300 9 | N 0.97600 -8.95000 25.45700 10 | O 4.37000 -6.90800 26.06500 11 | O 2.34900 -6.19100 29.68100 12 | C -0.98300 -8.12700 28.87400 13 | C -0.99200 -9.18400 26.80300 14 | C 1.62900 -9.20800 24.31600 15 | C -0.29200 -9.47100 25.58400 16 | H -0.48360 -7.50670 29.60350 17 | C -2.27100 -8.59300 29.15600 18 | C -2.29400 -9.68700 27.01500 19 | H 2.62020 -8.79870 24.18810 20 | C 1.08800 -9.98500 23.27700 21 | C -0.89700 -10.25800 24.58800 22 | H -2.74330 -8.35010 30.09640 23 | C -2.91700 -9.34500 28.24900 24 | C -2.88500 -10.49000 25.97200 25 | H 1.65660 -10.17740 22.37920 26 | C -0.17000 -10.49100 23.42600 27 | C -2.22800 -10.75600 24.82300 28 | H -3.91780 -9.69320 28.45780 29 | H -3.87860 -10.88860 26.11420 30 | H -0.60620 -11.07930 22.63230 31 | H -2.71030 -11.35450 24.06440 32 | -------------------------------------------------------------------------------- /examples/example_runs/monte_carlo/input.ini: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | metal_symbol = Re 3 | method = dock 4 | ncpu = 16 5 | 6 | [MC] 7 | mc_steps = 100 8 | parameter_file = metal_dock_optimize.dat 9 | 10 | [DOCKING] 11 | rmsd = True 12 | box_size = 20 13 | random_pos = True 14 | 15 | num_poses = 10 16 | ga_dock = True 17 | ga_dock_pop_size = 200 18 | ga_dock_num_evals = 2500000 19 | ga_dock_num_generations = 30000 20 | ga_dock_elitism = 2 21 | ga_dock_mutation_rate = 0.2 22 | ga_dock_crossover_rate = 0.80 23 | ga_dock_window_size = 20 24 | -------------------------------------------------------------------------------- /examples/example_runs/monte_carlo/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #SBATCH --nodes=1 # Number of nodes 3 | #SBATCH --ntasks=16 # Total number of MPI processes (tasks) 4 | #SBATCH --cpus-per-task=1 # Number of CPUs per ta 5 | #SBATCH -t 20:00:00 6 | #SBATCH -p genoa 7 | # 8 | 9 | module load 2023 10 | module load AMS/2023.101-intelmpi 11 | 12 | /gpfs/home6/mhakkennes/.micromamba/bin/envs/atm8.1.2/bin/python -u /home/mhakkennes/MetalDock/metaldock -i input.ini -m mc 13 | -------------------------------------------------------------------------------- /examples/example_runs/monte_carlo/slurm-9807103.out: -------------------------------------------------------------------------------- 1 | 2 | JOB STATISTICS 3 | ============== 4 | Job ID: 9807103 5 | Cluster: snellius 6 | User/Group: mhakkennes/mhakkennes 7 | State: FAILED (exit code 1) 8 | Nodes: 1 9 | Cores per node: 16 10 | CPU Utilized: 00:00:45 11 | CPU Efficiency: 4.93% of 00:15:12 core-walltime 12 | Job Wall-clock time: 00:00:57 13 | Memory Utilized: 124.81 MB 14 | Memory Efficiency: 0.44% of 28.00 GB 15 | -------------------------------------------------------------------------------- /examples/example_runs/no_vacancy_coordination_sphere/ADF/2bzh_B_HB1.xyz: -------------------------------------------------------------------------------- 1 | 43 2 | HB1 3 | O -19.17800 -33.89300 -4.93800 4 | C -20.25000 -33.70900 -4.72000 5 | Ru -22.02800 -33.35000 -4.53200 6 | C -23.70500 -31.89000 -4.85000 7 | C -22.47200 -31.36300 -5.35500 8 | C -22.01600 -32.21100 -6.37000 9 | C -22.94400 -33.27000 -6.52900 10 | C -23.98800 -33.06400 -5.59000 11 | N -21.83800 -32.85100 -2.45500 12 | C -21.52000 -31.66000 -1.87100 13 | N -22.52300 -35.17900 -3.65100 14 | C -22.93700 -36.44700 -3.93700 15 | C -23.20600 -37.17700 -2.72900 16 | C -23.62400 -38.50500 -2.79800 17 | C -23.74800 -39.06400 -4.05700 18 | C -23.48700 -38.33200 -5.22400 19 | C -23.08600 -37.01500 -5.18500 20 | C -22.94400 -36.27400 -1.66000 21 | C -22.55700 -35.07300 -2.32200 22 | C -22.96800 -36.20800 -0.25900 23 | C -23.36100 -37.23900 0.75000 24 | O -23.72500 -38.38800 0.58800 25 | C -22.63400 -35.02100 0.42600 26 | C -22.80900 -35.26100 1.86300 27 | N -23.22300 -36.59400 1.98300 28 | O -22.64300 -34.51600 2.80700 29 | C -22.23800 -33.79900 -0.24000 30 | C -22.19200 -33.88100 -1.65100 31 | C -21.85900 -32.54900 0.35000 32 | C -21.51400 -31.49400 -0.47100 33 | H -24.30490 -31.47130 -4.05550 34 | H -21.97940 -30.46550 -5.01120 35 | H -21.10700 -32.08010 -6.93840 36 | H -22.87040 -34.08410 -7.23490 37 | H -24.85370 -33.69680 -5.46120 38 | H -21.26530 -30.81950 -2.49960 39 | H -23.84190 -39.07350 -1.90590 40 | H -24.05520 -40.09570 -4.14380 41 | H -23.60400 -38.81560 -6.18260 42 | H -22.89730 -36.45390 -6.08830 43 | H -23.40340 -37.04320 2.86940 44 | H -21.84350 -32.43380 1.42370 45 | H -21.23970 -30.54200 -0.04100 46 | 47 | -------------------------------------------------------------------------------- /examples/example_runs/no_vacancy_coordination_sphere/ADF/input.ini: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | ncpu = 16 3 | metal_symbol = Ru 4 | method = dock 5 | 6 | [PROTEIN] 7 | pdb_file = 2bzh.pdb 8 | pH = 7.5 9 | clean_pdb = True 10 | 11 | [QM] 12 | engine = ADF 13 | basis_set = TZP 14 | functional_type = hybrid 15 | functional = B3LYP 16 | dispersion = GRIMME3 BJDAMP 17 | 18 | [METAL_COMPLEX] 19 | geom_opt = False 20 | xyz_file = 2bzh_B_HB1.xyz 21 | charge = 0 22 | spin = 0 23 | vacant_site = False 24 | 25 | [DOCKING] 26 | rmsd = True 27 | box_size = 20 28 | random_pos = True 29 | num_poses = 2 30 | 31 | -------------------------------------------------------------------------------- /examples/example_runs/no_vacancy_coordination_sphere/ADF/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #SBATCH -N 1 3 | #SBATCH --tasks-per-node=32 4 | #SBATCH -t 1:00:00 5 | #SBATCH -p genoa 6 | # 7 | 8 | module load 2023 9 | module load AMS/2023.101-intelmpi 10 | 11 | /gpfs/home6/mhakkennes/.micromamba/bin/envs/atm8.1.2/bin/python -u /home/mhakkennes/MetalDock/metaldock -i input.ini -m dock 12 | -------------------------------------------------------------------------------- /examples/example_runs/no_vacancy_coordination_sphere/GAUSSIAN/2bzh_B_HB1.xyz: -------------------------------------------------------------------------------- 1 | 43 2 | HB1 3 | O -19.17800 -33.89300 -4.93800 4 | C -20.25000 -33.70900 -4.72000 5 | Ru -22.02800 -33.35000 -4.53200 6 | C -23.70500 -31.89000 -4.85000 7 | C -22.47200 -31.36300 -5.35500 8 | C -22.01600 -32.21100 -6.37000 9 | C -22.94400 -33.27000 -6.52900 10 | C -23.98800 -33.06400 -5.59000 11 | N -21.83800 -32.85100 -2.45500 12 | C -21.52000 -31.66000 -1.87100 13 | N -22.52300 -35.17900 -3.65100 14 | C -22.93700 -36.44700 -3.93700 15 | C -23.20600 -37.17700 -2.72900 16 | C -23.62400 -38.50500 -2.79800 17 | C -23.74800 -39.06400 -4.05700 18 | C -23.48700 -38.33200 -5.22400 19 | C -23.08600 -37.01500 -5.18500 20 | C -22.94400 -36.27400 -1.66000 21 | C -22.55700 -35.07300 -2.32200 22 | C -22.96800 -36.20800 -0.25900 23 | C -23.36100 -37.23900 0.75000 24 | O -23.72500 -38.38800 0.58800 25 | C -22.63400 -35.02100 0.42600 26 | C -22.80900 -35.26100 1.86300 27 | N -23.22300 -36.59400 1.98300 28 | O -22.64300 -34.51600 2.80700 29 | C -22.23800 -33.79900 -0.24000 30 | C -22.19200 -33.88100 -1.65100 31 | C -21.85900 -32.54900 0.35000 32 | C -21.51400 -31.49400 -0.47100 33 | H -24.30490 -31.47130 -4.05550 34 | H -21.97940 -30.46550 -5.01120 35 | H -21.10700 -32.08010 -6.93840 36 | H -22.87040 -34.08410 -7.23490 37 | H -24.85370 -33.69680 -5.46120 38 | H -21.26530 -30.81950 -2.49960 39 | H -23.84190 -39.07350 -1.90590 40 | H -24.05520 -40.09570 -4.14380 41 | H -23.60400 -38.81560 -6.18260 42 | H -22.89730 -36.45390 -6.08830 43 | H -23.40340 -37.04320 2.86940 44 | H -21.84350 -32.43380 1.42370 45 | H -21.23970 -30.54200 -0.04100 46 | 47 | -------------------------------------------------------------------------------- /examples/example_runs/no_vacancy_coordination_sphere/GAUSSIAN/input.ini: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | metal_symbol = Ru 3 | method = dock 4 | ncpu = 32 5 | memory = 1500 6 | 7 | [PROTEIN] 8 | pdb_file = 2bzh.pdb 9 | pH = 7.5 10 | clean_pdb = True 11 | 12 | [QM] 13 | engine = GAUSSIAN 14 | basis_set = Def2TZVP 15 | functional_type = Hybrid 16 | functional = B3LYP 17 | dispersion = GD3BJ 18 | 19 | [METAL_COMPLEX] 20 | geom_opt =False 21 | xyz_file = 2bzh_B_HB1.xyz 22 | charge = 0 23 | spin = 0 24 | vacant_site = False 25 | 26 | [DOCKING] 27 | rmsd = True 28 | box_size = 20 29 | random_pos = True 30 | num_poses = 10 31 | 32 | -------------------------------------------------------------------------------- /examples/example_runs/no_vacancy_coordination_sphere/GAUSSIAN/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #SBATCH --nodes=1 # Number of nodes 3 | #SBATCH --ntasks=16 # Total number of MPI processes (tasks) 4 | #SBATCH --cpus-per-task=1 # Number of CPUs per ta 5 | #SBATCH -t 20:00:00 6 | #SBATCH -p genoa 7 | 8 | module load 2024 9 | module load Gaussian/g16.c02 10 | 11 | /gpfs/home6/mhakkennes/.micromamba/bin/envs/atm8.1.2/bin/python -u /home/mhakkennes/MetalDock/metaldock -i input.ini -m dock 12 | -------------------------------------------------------------------------------- /examples/example_runs/no_vacancy_coordination_sphere/ORCA/2bzh_B_HB1.xyz: -------------------------------------------------------------------------------- 1 | 43 2 | HB1 3 | O -19.17800 -33.89300 -4.93800 4 | C -20.25000 -33.70900 -4.72000 5 | Ru -22.02800 -33.35000 -4.53200 6 | C -23.70500 -31.89000 -4.85000 7 | C -22.47200 -31.36300 -5.35500 8 | C -22.01600 -32.21100 -6.37000 9 | C -22.94400 -33.27000 -6.52900 10 | C -23.98800 -33.06400 -5.59000 11 | N -21.83800 -32.85100 -2.45500 12 | C -21.52000 -31.66000 -1.87100 13 | N -22.52300 -35.17900 -3.65100 14 | C -22.93700 -36.44700 -3.93700 15 | C -23.20600 -37.17700 -2.72900 16 | C -23.62400 -38.50500 -2.79800 17 | C -23.74800 -39.06400 -4.05700 18 | C -23.48700 -38.33200 -5.22400 19 | C -23.08600 -37.01500 -5.18500 20 | C -22.94400 -36.27400 -1.66000 21 | C -22.55700 -35.07300 -2.32200 22 | C -22.96800 -36.20800 -0.25900 23 | C -23.36100 -37.23900 0.75000 24 | O -23.72500 -38.38800 0.58800 25 | C -22.63400 -35.02100 0.42600 26 | C -22.80900 -35.26100 1.86300 27 | N -23.22300 -36.59400 1.98300 28 | O -22.64300 -34.51600 2.80700 29 | C -22.23800 -33.79900 -0.24000 30 | C -22.19200 -33.88100 -1.65100 31 | C -21.85900 -32.54900 0.35000 32 | C -21.51400 -31.49400 -0.47100 33 | H -24.30490 -31.47130 -4.05550 34 | H -21.97940 -30.46550 -5.01120 35 | H -21.10700 -32.08010 -6.93840 36 | H -22.87040 -34.08410 -7.23490 37 | H -24.85370 -33.69680 -5.46120 38 | H -21.26530 -30.81950 -2.49960 39 | H -23.84190 -39.07350 -1.90590 40 | H -24.05520 -40.09570 -4.14380 41 | H -23.60400 -38.81560 -6.18260 42 | H -22.89730 -36.45390 -6.08830 43 | H -23.40340 -37.04320 2.86940 44 | H -21.84350 -32.43380 1.42370 45 | H -21.23970 -30.54200 -0.04100 46 | 47 | -------------------------------------------------------------------------------- /examples/example_runs/no_vacancy_coordination_sphere/ORCA/input.ini: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | metal_symbol = Ru 3 | method = dock 4 | ncpu = 16 5 | memory = 4000 6 | 7 | [PROTEIN] 8 | pdb_file = 2bzh.pdb 9 | pH = 7.5 10 | clean_pdb = True 11 | 12 | [QM] 13 | engine = ORCA 14 | orcasimpleinput = B3LYP D3BJ def2-TZVP 15 | orcablocks = %basis newECP Ru "def2-SD" end end 16 | 17 | [METAL_COMPLEX] 18 | geom_opt =True 19 | xyz_file = 2bzh_B_HB1.xyz 20 | charge = 0 21 | spin = 0 22 | vacant_site = False 23 | 24 | [DOCKING] 25 | rmsd = True 26 | box_size = 20 27 | random_pos = True 28 | num_poses = 10 29 | -------------------------------------------------------------------------------- /examples/example_runs/no_vacancy_coordination_sphere/ORCA/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #SBATCH -N 1 3 | #SBATCH --tasks-per-node=32 4 | #SBATCH -t 120:00:00 5 | #SBATCH -p genoa 6 | # 7 | 8 | module load 2024 9 | module load ORCA/6.0.1-gompi-2024a-avx2 10 | 11 | export ASE_ORCA_COMMAND='/sw/arch/RHEL9/EB_production/2024/software/ORCA/6.0.1-gompi-2024a-avx2/bin/orca PREFIX.inp > PREFIX.out' 12 | 13 | /gpfs/home6/mhakkennes/.micromamba/bin/envs/atm8.1.2/bin/python -u /home/mhakkennes/MetalDock/metaldock -i input.ini -m dock 14 | -------------------------------------------------------------------------------- /examples/example_runs/vacancy_coordination_sphere/ADF/1jzi_D_REP.xyz: -------------------------------------------------------------------------------- 1 | 29 2 | REP 3 | O 3.05200 -10.27700 28.42300 4 | C 2.53900 -9.34800 27.97200 5 | Re 1.65000 -7.80300 27.17600 6 | C 3.35300 -7.23900 26.46200 7 | C 2.11000 -6.78600 28.77000 8 | N -0.34500 -8.42100 27.73300 9 | N 0.97600 -8.95000 25.45700 10 | O 4.37000 -6.90800 26.06500 11 | O 2.34900 -6.19100 29.68100 12 | C -0.98300 -8.12700 28.87400 13 | C -0.99200 -9.18400 26.80300 14 | C 1.62900 -9.20800 24.31600 15 | C -0.29200 -9.47100 25.58400 16 | H -0.48360 -7.50670 29.60350 17 | C -2.27100 -8.59300 29.15600 18 | C -2.29400 -9.68700 27.01500 19 | H 2.62020 -8.79870 24.18810 20 | C 1.08800 -9.98500 23.27700 21 | C -0.89700 -10.25800 24.58800 22 | H -2.74330 -8.35010 30.09640 23 | C -2.91700 -9.34500 28.24900 24 | C -2.88500 -10.49000 25.97200 25 | H 1.65660 -10.17740 22.37920 26 | C -0.17000 -10.49100 23.42600 27 | C -2.22800 -10.75600 24.82300 28 | H -3.91780 -9.69320 28.45780 29 | H -3.87860 -10.88860 26.11420 30 | H -0.60620 -11.07930 22.63230 31 | H -2.71030 -11.35450 24.06440 32 | 33 | -------------------------------------------------------------------------------- /examples/example_runs/vacancy_coordination_sphere/ADF/input.ini: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | metal_symbol = Re 3 | method = dock 4 | ncpu = 16 5 | 6 | [PROTEIN] 7 | pdb_file = 1jzi.pdb 8 | pH = 7.0 9 | clean_pdb = True 10 | 11 | [QM] 12 | engine = ADF 13 | basis_set = TZP 14 | functional_type = Hybrid 15 | functional = B3LYP 16 | dispersion = GRIMME3 BJDAMP 17 | 18 | [METAL_COMPLEX] 19 | geom_opt = True 20 | xyz_file = 1jzi_D_REP.xyz 21 | charge = 1 22 | spin = 0 23 | vacant_site = True 24 | 25 | [DOCKING] 26 | dock_x = 1.65000 27 | dock_y = -7.80300 28 | dock_z = 27.17600 29 | 30 | rmsd = True 31 | box_size = 20 32 | random_pos = True 33 | 34 | num_poses = 3 35 | ga_dock = True 36 | ga_dock_pop_size = 200 37 | ga_dock_num_evals = 2500000 38 | ga_dock_num_generations = 30000 39 | ga_dock_elitism = 2 40 | ga_dock_mutation_rate = 0.2 41 | ga_dock_crossover_rate = 0.80 42 | ga_dock_window_size = 20 43 | -------------------------------------------------------------------------------- /examples/example_runs/vacancy_coordination_sphere/ADF/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #SBATCH --nodes=1 # Number of nodes 3 | #SBATCH --ntasks=16 # Total number of MPI processes (tasks) 4 | #SBATCH --cpus-per-task=1 # Number of CPUs per ta 5 | #SBATCH -t 20:00:00 6 | #SBATCH -p genoa 7 | # 8 | 9 | module load 2023 10 | module load AMS/2023.101-intelmpi 11 | 12 | /gpfs/home6/mhakkennes/.micromamba/bin/envs/atm8.1.2/bin/python -u /home/mhakkennes/MetalDock/metaldock -i input.ini -m dock 13 | -------------------------------------------------------------------------------- /examples/example_runs/vacancy_coordination_sphere/GAUSSIAN/1jzi_D_REP.xyz: -------------------------------------------------------------------------------- 1 | 29 2 | REP 3 | O 3.05200 -10.27700 28.42300 4 | C 2.53900 -9.34800 27.97200 5 | Re 1.65000 -7.80300 27.17600 6 | C 3.35300 -7.23900 26.46200 7 | C 2.11000 -6.78600 28.77000 8 | N -0.34500 -8.42100 27.73300 9 | N 0.97600 -8.95000 25.45700 10 | O 4.37000 -6.90800 26.06500 11 | O 2.34900 -6.19100 29.68100 12 | C -0.98300 -8.12700 28.87400 13 | C -0.99200 -9.18400 26.80300 14 | C 1.62900 -9.20800 24.31600 15 | C -0.29200 -9.47100 25.58400 16 | H -0.48360 -7.50670 29.60350 17 | C -2.27100 -8.59300 29.15600 18 | C -2.29400 -9.68700 27.01500 19 | H 2.62020 -8.79870 24.18810 20 | C 1.08800 -9.98500 23.27700 21 | C -0.89700 -10.25800 24.58800 22 | H -2.74330 -8.35010 30.09640 23 | C -2.91700 -9.34500 28.24900 24 | C -2.88500 -10.49000 25.97200 25 | H 1.65660 -10.17740 22.37920 26 | C -0.17000 -10.49100 23.42600 27 | C -2.22800 -10.75600 24.82300 28 | H -3.91780 -9.69320 28.45780 29 | H -3.87860 -10.88860 26.11420 30 | H -0.60620 -11.07930 22.63230 31 | H -2.71030 -11.35450 24.06440 32 | 33 | -------------------------------------------------------------------------------- /examples/example_runs/vacancy_coordination_sphere/GAUSSIAN/input.ini: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | metal_symbol = Re 3 | method = dock 4 | ncpu = 32 5 | memory = 1500 6 | 7 | [PROTEIN] 8 | pdb_file = 1jzi.pdb 9 | pH = 7.0 10 | clean_pdb = True 11 | 12 | [QM] 13 | engine = GAUSSIAN 14 | basis_set = Def2TZVP 15 | functional_type = Hybrid 16 | functional = B3LYP 17 | dispersion = GD3BJ 18 | 19 | [METAL_COMPLEX] 20 | geom_opt = True 21 | xyz_file = 1jzi_D_REP.xyz 22 | charge = 1 23 | spin = 0 24 | vacant_site = True 25 | 26 | [DOCKING] 27 | dock_x = 1.65000 28 | dock_y = -7.80300 29 | dock_z = 27.17600 30 | 31 | rmsd = True 32 | box_size = 20 33 | random_pos = True 34 | 35 | num_poses = 10 36 | ga_dock = True 37 | ga_dock_pop_size = 200 38 | ga_dock_num_evals = 2500000 39 | ga_dock_num_generations = 30000 40 | ga_dock_elitism = 2 41 | ga_dock_mutation_rate = 0.2 42 | ga_dock_crossover_rate = 0.80 43 | ga_dock_window_size = 20 44 | -------------------------------------------------------------------------------- /examples/example_runs/vacancy_coordination_sphere/GAUSSIAN/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #SBATCH -N 1 3 | #SBATCH --tasks-per-node=32 4 | #SBATCH -t 10:00:00 5 | #SBATCH -p genoa 6 | # 7 | 8 | 9 | module load 2024 10 | module load Gaussian/g16.c02 11 | 12 | /gpfs/home6/mhakkennes/.micromamba/bin/envs/atm8.1.2/bin/python -u /home/mhakkennes/MetalDock/metaldock -i input.ini -m dock 13 | -------------------------------------------------------------------------------- /examples/example_runs/vacancy_coordination_sphere/ORCA/1jzi_D_REP.xyz: -------------------------------------------------------------------------------- 1 | 29 2 | REP 3 | O 3.05200 -10.27700 28.42300 4 | C 2.53900 -9.34800 27.97200 5 | Re 1.65000 -7.80300 27.17600 6 | C 3.35300 -7.23900 26.46200 7 | C 2.11000 -6.78600 28.77000 8 | N -0.34500 -8.42100 27.73300 9 | N 0.97600 -8.95000 25.45700 10 | O 4.37000 -6.90800 26.06500 11 | O 2.34900 -6.19100 29.68100 12 | C -0.98300 -8.12700 28.87400 13 | C -0.99200 -9.18400 26.80300 14 | C 1.62900 -9.20800 24.31600 15 | C -0.29200 -9.47100 25.58400 16 | H -0.48360 -7.50670 29.60350 17 | C -2.27100 -8.59300 29.15600 18 | C -2.29400 -9.68700 27.01500 19 | H 2.62020 -8.79870 24.18810 20 | C 1.08800 -9.98500 23.27700 21 | C -0.89700 -10.25800 24.58800 22 | H -2.74330 -8.35010 30.09640 23 | C -2.91700 -9.34500 28.24900 24 | C -2.88500 -10.49000 25.97200 25 | H 1.65660 -10.17740 22.37920 26 | C -0.17000 -10.49100 23.42600 27 | C -2.22800 -10.75600 24.82300 28 | H -3.91780 -9.69320 28.45780 29 | H -3.87860 -10.88860 26.11420 30 | H -0.60620 -11.07930 22.63230 31 | H -2.71030 -11.35450 24.06440 32 | 33 | -------------------------------------------------------------------------------- /examples/example_runs/vacancy_coordination_sphere/ORCA/input.ini: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | metal_symbol = Re 3 | method = dock 4 | ncpu = 16 5 | 6 | [PROTEIN] 7 | pdb_file = 1jzi.pdb 8 | pH = 7.0 9 | clean_pdb = True 10 | 11 | [QM] 12 | engine = ORCA 13 | orcasimpleinput = B3LYP D3BJ def2-TZVP 14 | orcablocks = %basis newECP Ru "def2-SD" end end 15 | 16 | [METAL_COMPLEX] 17 | geom_opt = False 18 | xyz_file = 1jzi_D_REP.xyz 19 | charge = 1 20 | spin = 0 21 | vacant_site = True 22 | 23 | [DOCKING] 24 | dock_x = 1.65000 25 | dock_y = -7.80300 26 | dock_z = 27.17600 27 | 28 | rmsd = True 29 | box_size = 20 30 | random_pos = True 31 | 32 | num_poses = 10 33 | ga_dock = True 34 | ga_dock_pop_size = 200 35 | ga_dock_num_evals = 2500000 36 | ga_dock_num_generations = 30000 37 | ga_dock_elitism = 2 38 | ga_dock_mutation_rate = 0.2 39 | ga_dock_crossover_rate = 0.80 40 | ga_dock_window_size = 20 41 | 42 | -------------------------------------------------------------------------------- /examples/example_runs/vacancy_coordination_sphere/ORCA/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #SBATCH -N 1 3 | #SBATCH --tasks-per-node=32 4 | #SBATCH -t 10:00:00 5 | #SBATCH -p genoa 6 | # 7 | 8 | module load 2024 9 | module load ORCA/6.0.1-gompi-2024a-avx2 10 | 11 | export ASE_ORCA_COMMAND='/sw/arch/RHEL9/EB_production/2024/software/ORCA/6.0.1-gompi-2024a-avx2/bin/orca PREFIX.inp > PREFIX.out' 12 | 13 | /gpfs/home6/mhakkennes/.micromamba/bin/envs/atm8.1.2/bin/python -u /home/mhakkennes/MetalDock/metaldock -i input.ini -m dock 14 | -------------------------------------------------------------------------------- /metaldock: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from src.metal_dock.main import main 4 | 5 | if __name__ == "__main__": 6 | main() 7 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "MetalDock_MatthijsHak" 7 | version = "1.0.0" 8 | authors = [ 9 | { name = "Matthijs Hakkennes", email = "m.l.a.hakkennes@lic.leidenuniv.nl" }, 10 | ] 11 | description = "Package to dock metal-organic complexes to biomolecules" 12 | readme = "README.md" 13 | classifiers = [ 14 | "Programming Language :: Python :: 3", 15 | "License :: OSI Approved :: MIT License", 16 | "Operating System :: POSIX :: Linux", 17 | "Operating System :: MacOS :: MacOS X", 18 | ] 19 | 20 | [project.urls] 21 | "Homepage" = "https://github.com/MatthijsHak/MetalDock" 22 | "Bug Tracker" = "https://github.com/MatthijsHak/MetalDock/issues" 23 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = MetalDock 3 | version = 1.0.0 4 | 5 | [options] 6 | zip_safe = True 7 | include_package_data = True 8 | packages = find: 9 | package_dir= 10 | =src 11 | 12 | [options.packages.find] 13 | where=src 14 | 15 | [options.package_data] 16 | example = path 17 | * = README.md 18 | 19 | [entry_points] 20 | console_scripts = 21 | metaldock = metal_dock.main:main 22 | -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MatthijsHak/MetalDock/73a52ccf1bd1a8d199f80405ee9da70135c7cda6/src/.DS_Store -------------------------------------------------------------------------------- /src/external/AutoDock/autodock4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MatthijsHak/MetalDock/73a52ccf1bd1a8d199f80405ee9da70135c7cda6/src/external/AutoDock/autodock4 -------------------------------------------------------------------------------- /src/external/AutoDock/autogrid4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MatthijsHak/MetalDock/73a52ccf1bd1a8d199f80405ee9da70135c7cda6/src/external/AutoDock/autogrid4 -------------------------------------------------------------------------------- /src/external/AutoDockTools/AutoDockBondClassifier.py: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # $Id: AutoDockBondClassifier.py,v 1.9.8.1 2016/02/11 09:24:06 annao Exp $ 4 | # 5 | # 6 | # 7 | # 8 | 9 | 10 | from MolKit.bondClassifier import BondClassifier 11 | from MolKit.bondSelector import AmideBondSelector, PeptideBackBoneBondSelector 12 | from MolKit.bondSelector import HydrogenRotatorBondSelector, RotatableBondSelector 13 | from MolKit.bondSelector import LeafBondSelector, CycleBondSelector 14 | from MolKit.bondSelector import GuanidiniumBondSelector, BondOrderBondSelector 15 | from MolKit.bondSelector import AromaticCycleBondSelector2 16 | from MolKit.molecule import BondSet 17 | 18 | def dist(c1, c2): 19 | import numpy, math 20 | d = numpy.array(c2) - numpy.array(c1) 21 | ans = math.sqrt(numpy.sum(d*d)) 22 | return round(ans, 3) 23 | 24 | 25 | class AutoDockBondClassifier(BondClassifier): 26 | 27 | def __init__(self, tolerance=0.01, detectAll=True): 28 | self.detect_all_cycles = detectAll 29 | self.d = { 30 | 'amide':AmideBondSelector(), 31 | 'ppbb':PeptideBackBoneBondSelector(), 32 | 'leaf':LeafBondSelector(), 33 | 'cycle':CycleBondSelector(), 34 | 'rotatable':RotatableBondSelector(), 35 | 'bondOrder2':BondOrderBondSelector(2), 36 | 'hydrogenRotators':HydrogenRotatorBondSelector(), 37 | 'guanidinium':GuanidiniumBondSelector(), 38 | 'aromatic': AromaticCycleBondSelector2() 39 | 40 | } 41 | BondClassifier.__init__(self, self.d) 42 | #used to detect colinear atoms 43 | #if dist1+dist2=dist1+dist2: 83 | #print "adding ", b2, 'to leaf bonds' 84 | resultDict['leaf'].append(b2) 85 | if b2 in resultDict['rotatable']: 86 | resultDict['rotatable'].remove(b2) 87 | elif len(at2.bonds)==1: 88 | at2.leaf = 1 89 | if len(at1.bonds)==2: 90 | dist1 = dist(at1.coords, at2.coords) 91 | #find neighbor of at1 and check bond distances 92 | b2 = at1.bonds[0] 93 | if b2==b: 94 | b2 = at1.bonds[1] 95 | neighbor = b2.atom1 96 | if neighbor==at1: 97 | neighbor = b2.atom2 98 | dist2 = dist(neighbor.coords, at1.coords) 99 | dist13 = dist(at2.coords, neighbor.coords) 100 | if dist13+self.tolerance>=dist1+dist2: 101 | resultDict['leaf'].append(b2) 102 | #print "2: adding ", b2, 'to leaf bonds' 103 | b2.possibleTors=0 104 | if b2 in resultDict['rotatable']: 105 | resultDict['rotatable'].remove(b2) 106 | 107 | #8/16:NOTE only select from rotatables for amide+ guanidinium 108 | for k in ['amide', 'guanidinium']: 109 | resultDict[k] = self.d[k].select(rotatables) 110 | return resultDict 111 | 112 | 113 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/LICENSE: -------------------------------------------------------------------------------- 1 | This software is copyrighted by Michel F. Sanner (sanner@scripps.edu) and TSRI. 2 | The following terms apply to all files associated with the software 3 | unless explicitly disclaimed in individual files. 4 | 5 | MGLTOOLS SOFTWARE LICENSE AGREEMENT. 6 | 7 | 1. Grant Of Limited License; Software Use Restrictions. The programs 8 | received by you will be used only for NON COMMERCIAL purposes. 9 | This license is issued to you as an individual. 10 | 11 | For COMMERCIAL use done with the software please contact Michel F. 12 | Sanner for details about commercial usage license agreements. 13 | 14 | For any question regarding license agreements, please contact 15 | Michel Sanner: 16 | TSRI, Molecular Biology Department, TCP 26, 17 | 10550 North Torrey Pines Road, La Jolla, CA 92037 18 | sanner@scripps.edu 19 | tel (858) 784-7742 20 | fax (858) 784-2341 21 | 22 | 2. COMMERCIAL USAGE is defined as revenues generating activities. These 23 | include using this software for consulting activities and selling 24 | applications built on top of, or using this software. Scientific 25 | research in an academic environment and teaching are considered 26 | NON COMMERCIAL. 27 | 28 | 3. Copying Restrictions. You will not sell or otherwise distribute commercially 29 | these programs or derivatives to any other party, whether with or without 30 | consideration. 31 | 32 | 4. Ownership of Software. You will not obtain, and will not attempt to 33 | obtain copyright coverage thereon without the express purpose written 34 | consent of The Scripps Research Institute and Dr. Sanner. 35 | 36 | 5. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY 37 | FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 38 | ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY 39 | DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE 40 | POSSIBILITY OF SUCH DAMAGE. 41 | 42 | 6. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, 43 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, 44 | FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE 45 | IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE 46 | NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 47 | MODIFICATIONS. 48 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/LICENSE: -------------------------------------------------------------------------------- 1 | This software is copyrighted by Michel F. Sanner (sanner@scripps.edu) 2 | The following terms apply to all files associated with the software 3 | unless explicitly disclaimed in individual files. 4 | 5 | MGLTOOLS SOFTWARE LICENSE AGREEMENT. 6 | 7 | 1. Grant Of Limited License; Software Use Restrictions. The programs 8 | received by you will be used only for NON COMMERCIAL purposes. 9 | This license is issued to you as an individual. 10 | 11 | For COMMERCIAL use done with the software please contact Michel F. 12 | Sanner for details about commercial usage license agreements. 13 | 14 | For any question regarding license agreements, please contact 15 | Michel Sanner: 16 | TSRI, Molecular Biology Department, TCP 26, 17 | 10550 North Torrey Pines Road, La Jolla, CA 92037 18 | sanner@scripps.edu 19 | tel (858) 784-7742 20 | fax (858) 784-2341 21 | 22 | 2. COMMERCIAL USAGE is defined as revenues generating activities. These 23 | include using this software for consulting activities and selling 24 | applications built on top of, or using this software. Scientific 25 | research in an academic environment and teaching are considered 26 | NON COMMERCIAL. 27 | 28 | 3. Copying Restrictions. You will not sell or otherwise distribute commercially 29 | these programs or derivatives to any other party, whether with or without 30 | consideration. 31 | 32 | 4. Ownership of Software. You will not obtain, and will not attempt to 33 | obtain copyright coverage thereon without the express purpose written 34 | consent of The Scripps Research Institute and Dr. Sanner. 35 | 36 | 5. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY 37 | FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 38 | ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY 39 | DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE 40 | POSSIBILITY OF SUCH DAMAGE. 41 | 42 | 6. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, 43 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, 44 | FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE 45 | IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE 46 | NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 47 | MODIFICATIONS. 48 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/PDBresidueNames.py: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # 3 | # Author: Michel F. SANNER 4 | # 5 | # Copyright: M. Sanner TSRI 2010 6 | # 7 | # 8 | ############################################################################# 9 | 10 | # 11 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/MolKit/PDBresidueNames.py,v 1.7 2012/05/15 17:42:23 sanner Exp $ 12 | # 13 | # $Id: PDBresidueNames.py,v 1.7 2012/05/15 17:42:23 sanner Exp $ 14 | # 15 | ## 16 | ## This file provides residues names used in PDB for various type of entities 17 | ## 18 | 19 | 20 | DNAnames = { 21 | 'DC':'D', 'DG':'G', 'DA':'A', 'DT':'T', 'T':'T', 'DI':'I', 'N':'N', 22 | } 23 | 24 | RNAnames = { 25 | 'C':'C', 'G':'G', 'A':'A', 'U':'U', 'I':'I', 'N':'N', 26 | } 27 | 28 | Nucleotides = DNAnames.copy() 29 | Nucleotides.update(RNAnames) 30 | 31 | 32 | AAnames = { 33 | 'ALA':'A', 'CYS':'C', 'ASP':'D', 'GLU':'E', 'PHE':'F', 'GLY':'G', 34 | 'HIS':'H', 'ILE':'I', 'LYS':'K', 'LEU':'L', 'MET':'M', 'ASN':'N', 35 | 'PRO':'P', 'GLN':'Q', 'ARG':'R', 'SER':'S', 'THR':'T', 'VAL':'V', 36 | 'TRP':'W', 'TYR':'Y', 37 | # the follwould be added automatically if the 38 | # MODRES ris present in the pdb file but we put 39 | # them herays 40 | 'HID':'?', 'HSP':'?', 'HIE':'?', 'HIP':'?', 'CYX':'?', 41 | 'CSS':'?', 'ACE':'?', 'MSE':'?', '5HP':'?', 'SOC':'?', 42 | } 43 | 44 | ## 45 | ## list of resames for ions taken from 46 | ## http://decogroup.org/ion_list.txt 47 | ## 48 | ionNames = { 49 | '1CU':'?', 50 | '2HP':'?', 51 | '2MO':'?', 52 | '2OF':'?', 53 | '3CO':'?', 54 | '3MT':'?', 55 | '3NI':'?', 56 | '4MO':'?', 57 | '543':'?', 58 | '6MO':'?', 59 | 'ACT':'?', 60 | 'AG':'?', 61 | 'AL':'?', 62 | 'ALF':'?', 63 | 'ATH':'?', 64 | 'AU':'?', 65 | 'AU3':'?', 66 | 'AUC':'?', 67 | 'AZI':'?', 68 | 'BA':'?', 69 | 'BCT':'?', 70 | 'BEF':'?', 71 | 'BF4':'?', 72 | 'BO4':'?', 73 | 'BR':'?', 74 | 'CA':'?', 75 | 'CAC':'?', 76 | 'CD':'?', 77 | 'CD1':'?', 78 | 'CD3':'?', 79 | 'CD5':'?', 80 | 'CE':'?', 81 | 'CHT':'?', 82 | 'CL':'?', 83 | 'CO':'?', 84 | 'CO3':'?', 85 | 'CO5':'?', 86 | 'CON':'?', 87 | 'CR':'?', 88 | 'CS':'?', 89 | 'CU':'?', 90 | 'CU1':'?', 91 | 'CUA':'?', 92 | 'CUZ':'?', 93 | 'CYN':'?', 94 | 'DMI':'?', 95 | 'E4N':'?', 96 | 'EMC':'?', 97 | 'EU':'?', 98 | 'EU3':'?', 99 | 'F':'?', 100 | 'FE':'?', 101 | 'FE2':'?', 102 | 'FPO':'?', 103 | 'GA':'?', 104 | 'GD3':'?', 105 | 'HAI':'?', 106 | 'HG':'?', 107 | 'HGC':'?', 108 | 'HO':'?', 109 | 'IN':'?', 110 | 'IOD':'?', 111 | 'IR':'?', 112 | 'IR3':'?', 113 | 'IRI':'?', 114 | 'IUM':'?', 115 | 'K':'?', 116 | 'KO4':'?', 117 | 'LA':'?', 118 | 'LCO':'?', 119 | 'LCP':'?', 120 | 'LI':'?', 121 | 'LU':'?', 122 | 'MAC':'?', 123 | 'MG':'?', 124 | 'MH2':'?', 125 | 'MH3':'?', 126 | 'MLI':'?', 127 | 'MLT':'?', 128 | 'MMC':'?', 129 | 'MN':'?', 130 | 'MN3':'?', 131 | 'MN5':'?', 132 | 'MO1':'?', 133 | 'MO2':'?', 134 | 'MO3':'?', 135 | 'MO4':'?', 136 | 'MO5':'?', 137 | 'MO6':'?', 138 | 'MOO':'?', 139 | 'MOS':'?', 140 | 'MW1':'?', 141 | 'MW2':'?', 142 | 'MW3':'?', 143 | 'NA':'?', 144 | 'NA2':'?', 145 | 'NA5':'?', 146 | 'NA6':'?', 147 | 'NAO':'?', 148 | 'NAW':'?', 149 | 'NC':'?', 150 | 'NET':'?', 151 | 'NH4':'?', 152 | 'NI':'?', 153 | 'NI1':'?', 154 | 'NI2':'?', 155 | 'NI3':'?', 156 | 'NO2':'?', 157 | 'NO3':'?', 158 | 'O4M':'?', 159 | 'OAA':'?', 160 | 'OC1':'?', 161 | 'OC2':'?', 162 | 'OC3':'?', 163 | 'OC4':'?', 164 | 'OC5':'?', 165 | 'OC6':'?', 166 | 'OC7':'?', 167 | 'OCL':'?', 168 | 'OCM':'?', 169 | 'OCN':'?', 170 | 'OCO':'?', 171 | 'OF1':'?', 172 | 'OF2':'?', 173 | 'OF3':'?', 174 | 'OH':'?', 175 | 'OS':'?', 176 | 'OXL':'?', 177 | 'PB':'?', 178 | 'PBM':'?', 179 | 'PD':'?', 180 | 'PER':'?', 181 | 'PI':'?', 182 | 'PO3':'?', 183 | 'PO4':'?', 184 | 'PR':'?', 185 | 'PT':'?', 186 | 'PT4':'?', 187 | 'PTN':'?', 188 | 'RB':'?', 189 | 'RHD':'?', 190 | 'RU':'?', 191 | 'SB':'?', 192 | 'SCN':'?', 193 | 'SE4':'?', 194 | 'SM':'?', 195 | 'SMO':'?', 196 | 'SO3':'?', 197 | 'SO4':'?', 198 | 'SOH':'?', 199 | 'SR':'?', 200 | 'TB':'?', 201 | 'TCN':'?', 202 | 'TEA':'?', 203 | 'THE':'?', 204 | 'TL':'?', 205 | 'TMA':'?', 206 | 'TRA':'?', 207 | 'UNX':'?', 208 | 'V':'?', 209 | 'VO4':'?', 210 | 'W':'?', 211 | 'WO5':'?', 212 | 'Y1':'?', 213 | 'YB':'?', 214 | 'YT3':'?', 215 | 'ZN':'?', 216 | 'ZN2':'?', 217 | 'ZN3':'?', 218 | 'ZNO':'?', 219 | 'ZO3':'?', 220 | } 221 | 222 | waterNames = {'HOH':'?', 'WAT':'?'} 223 | 224 | allResidueNames = {} 225 | allResidueNames.update(waterNames) 226 | allResidueNames.update(RNAnames) 227 | allResidueNames.update(AAnames) 228 | allResidueNames.update(DNAnames) 229 | allResidueNames.update(ionNames) 230 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/bondClassifier.py: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # 3 | # Author: Ruth Huey, William M. Lindstrom 4 | # 5 | # Copyright: R. Huey, W. M. Lindstrom TRSI 2003 6 | # 7 | ############################################################################# 8 | 9 | # 10 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/MolKit/bondClassifier.py,v 1.3 2004/04/06 23:29:50 rhuey Exp $ 11 | # 12 | # $Id: bondClassifier.py,v 1.3 2004/04/06 23:29:50 rhuey Exp $ 13 | # 14 | # 15 | # 16 | 17 | """ 18 | This module implements a classifier which select bonds based on a 19 | dictionary of key, bondSelector. 20 | It returns a dictionary with keys the specified bond types and 21 | values the bonds which have been classified. 22 | """ 23 | 24 | from MolKit.molecule import BondSet 25 | 26 | 27 | 28 | class BondClassifier: 29 | """ Base class that sorts bonds based on an input dictionary with keys 30 | and bondSelector values 31 | """ 32 | 33 | 34 | def __init__(self, d={}): 35 | self.dict = d 36 | 37 | 38 | def classify(self, bonds=None): 39 | """ 40 | select using each bondselector (the values of the dict); store result 41 | in resultDict and return the result dict when finished... 42 | """ 43 | #make sure that classify is called with some bonds 44 | assert isinstance(bonds, BondSet) 45 | resultDict = {} 46 | for k, v in list(self.dict.items()): 47 | resultDict[k] = v.select(bonds) 48 | return resultDict 49 | 50 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/chargeMass.py: -------------------------------------------------------------------------------- 1 | def getChargeMass(atoms): 2 | elist = [] 3 | totmass = 0.0 4 | 5 | for a in atoms: 6 | if a.element=='H': 7 | e=1.0 8 | totmass+=1.00794 9 | elif a.element=='C': 10 | e=6.0 11 | totmass+=12.0107 12 | elif a.element=='AU': 13 | e=79.0 14 | totmass+=196.96655 15 | elif a.element=='N': 16 | e=7.0 17 | totmass+=14.00674 18 | elif a.element=='O': 19 | e=8.0 20 | totmass+=15.9994 21 | elif a.element=='P': 22 | e=15.0 23 | totmass+=30.973761 24 | elif a.element=='S': 25 | e=16.0 26 | totmass+=32.066 27 | elif a.element=='W': 28 | e=18.0 29 | totmass+=1.00794*2+15.9994 # ficticious water 'atom' 30 | else: 31 | print("skipping unknown atom %s"%a.element) 32 | e = -1 33 | elist.append(e) 34 | 35 | return elist, totmass 36 | 37 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/data/CVS/Entries: -------------------------------------------------------------------------------- 1 | /__init__.py/1.1/Wed Jan 23 20:18:31 2002//Trc-1-5-7 2 | /all.in/1.1/Wed Feb 13 17:15:58 2002//Trc-1-5-7 3 | /all_amino94.in/1.4/Mon Dec 17 18:20:31 2001//Trc-1-5-7 4 | /all_amino94_dat.py/1.2/Thu Aug 29 15:40:24 2002//Trc-1-5-7 5 | /all_aminoct94.in/1.1/Thu Nov 29 02:25:23 2001//Trc-1-5-7 6 | /all_aminoct94_dat.py/1.2/Thu Aug 29 15:40:41 2002//Trc-1-5-7 7 | /all_aminont94.in/1.1/Thu Nov 29 02:25:23 2001//Trc-1-5-7 8 | /all_aminont94_dat.py/1.2/Thu Aug 29 15:40:54 2002//Trc-1-5-7 9 | /all_dat.py/1.3/Thu Aug 29 15:48:01 2002//Trc-1-5-7 10 | /all_nuc94.in/1.1/Wed Feb 13 17:17:33 2002//Trc-1-5-7 11 | /all_nuc94_dat.py/1.3/Thu Aug 29 15:49:03 2002//Trc-1-5-7 12 | /allct.in/1.1/Wed Feb 13 17:16:26 2002//Trc-1-5-7 13 | /allct_dat.py/1.2/Thu Aug 29 15:42:19 2002//Trc-1-5-7 14 | /allnt.in/1.1/Wed Feb 13 17:16:49 2002//Trc-1-5-7 15 | /allnt_dat.py/1.2/Thu Aug 29 15:42:32 2002//Trc-1-5-7 16 | /build_all_in.py/1.4/Fri Aug 29 17:50:16 2003//Trc-1-5-7 17 | /nh2e.in/1.1/Wed Feb 13 17:19:34 2002//Trc-1-5-7 18 | /nh2e_dat.py/1.1/Wed Feb 13 17:29:48 2002//Trc-1-5-7 19 | /opls_nacl.in/1.1/Wed Feb 13 17:20:43 2002//Trc-1-5-7 20 | /opls_nacl_dat.py/1.1/Wed Feb 13 17:27:05 2002//Trc-1-5-7 21 | /opls_uni.in/1.1/Wed Feb 13 17:22:18 2002//Trc-1-5-7 22 | /opls_uni_dat.py/1.3/Thu Aug 29 15:49:39 2002//Trc-1-5-7 23 | /opls_unict.in/1.1/Wed Feb 13 17:23:10 2002//Trc-1-5-7 24 | /opls_unict_dat.py/1.1/Wed Feb 13 17:28:18 2002//Trc-1-5-7 25 | /opls_unint.in/1.1/Wed Feb 13 17:23:37 2002//Trc-1-5-7 26 | /opls_unint_dat.py/1.1/Wed Feb 13 17:26:34 2002//Trc-1-5-7 27 | /parm94.dat/1.1/Thu Nov 29 02:25:23 2001//Trc-1-5-7 28 | /qkollua.py/1.1/Tue Nov 11 23:57:19 2003//Trc-1-5-7 29 | /rotamer.def/1.2.4.1/Wed Aug 26 19:38:50 2015//Trc-1-5-7 30 | /uni_dat.py/1.1/Wed Feb 13 17:28:48 2002//Trc-1-5-7 31 | /unict_dat.py/1.1/Wed Feb 13 17:27:36 2002//Trc-1-5-7 32 | /unint_dat.py/1.1/Wed Feb 13 17:25:59 2002//Trc-1-5-7 33 | D 34 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/data/CVS/Repository: -------------------------------------------------------------------------------- 1 | python/packages/share1.5/MolKit/data 2 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/data/CVS/Root: -------------------------------------------------------------------------------- 1 | :pserver:anonymous@orca.scripps.edu:/mnt/raid/services/cvs 2 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/data/CVS/Tag: -------------------------------------------------------------------------------- 1 | Trc-1-5-7 2 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/data/__init__.py: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # 3 | # Author: Michel F. SANNER, Sophie COON 4 | # 5 | # Copyright: M. Sanner TSRI 2000 6 | # 7 | ############################################################################# 8 | 9 | # 10 | #$Header: /mnt/raid/services/cvs/python/packages/share1.5/MolKit/data/__init__.py,v 1.1 2002/01/23 20:18:31 rhuey Exp $ 11 | # 12 | #$Id: __init__.py,v 1.1 2002/01/23 20:18:31 rhuey Exp $ 13 | # 14 | 15 | import string 16 | 17 | def Read(filename): 18 | from MolKit.pdbParser import PdbParser, PdbqParser,PdbqsParser, PQRParser 19 | from MolKit.mol2Parser import Mol2Parser 20 | ext = filename.split('.') 21 | if ext[-1]=='pdb': 22 | parser = PdbParser(filename) 23 | 24 | elif ext[-1]=='pdbq': 25 | parser = PdbqParser(filename) 26 | 27 | elif ext[-1]=='pdbqs': 28 | parser = PdbqsParser(filename) 29 | 30 | elif ext[-1]=='pqr': 31 | parser = PQRParser(filename) 32 | 33 | elif ext[-1]=='mol2': 34 | parser = Mol2Parser(filename) 35 | 36 | else: 37 | print("File Format unknown can't parse it") 38 | return [] 39 | molecules = parser.parse() 40 | return molecules 41 | 42 | def WritePDB(filename,node): 43 | from MolKit.pdbWriter import PdbWriter 44 | writer = PdbWriter() 45 | writer.write(filename, node) 46 | 47 | 48 | ## def getNodesByMolecule(self, nodes, molecules,nodeType=None): 49 | ## """ moleculeSet, [nodeSet, nodeSet] <- getNodesByMolecule(nodes) 50 | ## nodes can be either: a string, a TreeNode or a TreeNodeSet. 51 | ## This method returns a molecule set and for each molecule a TreeNodeSet 52 | ## of the nodes belonging to this molecule. 53 | ## 'nodeType' enables a desired type of nodes to be returned for each 54 | ## molecule 55 | ## """ 56 | 57 | ## # if it is a string, get a bunch of nodes from the string 58 | ## if type(nodes)==types.StringType: 59 | ## nodes = molecules.NodesFromName(nodes) 60 | 61 | ## assert issubclass(nodes.__class__, TreeNode) or \ 62 | ## issubclass(nodes.__class__, TreeNodeSet) 63 | 64 | ## # if nodes is a single TreeNode make it a singleton TreeNodeSet 65 | ## if issubclass(nodes.__class__, TreeNode): 66 | ## nodes = nodes.setClass([nodes]) 67 | 68 | ## if len(nodes)==0: return MoleculeSet([]), [] 69 | 70 | ## # catch the case when nodes is already a MoleculeSet 71 | ## if nodes.elementType in [Molecule, Protein]: 72 | ## molecules = nodes 73 | ## else: # get the set of molecules 74 | ## molecules = nodes.top.uniq() 75 | 76 | ## # build the set of nodes for each molecule 77 | ## nodeSets = [] 78 | 79 | ## # find out the type of the nodes we want to return 80 | ## searchType=0 81 | ## if nodeType is None: 82 | ## Klass = nodes.elementType # class of objects in that set 83 | ## else: 84 | ## assert issubclass(nodeType, TreeNode) 85 | ## Klass = nodeType 86 | ## if Klass != nodes.elementType: 87 | ## searchType=1 88 | 89 | ## for mol in molecules: 90 | ## # get set of nodes for this molecule 91 | ## mol_nodes = nodes.get(lambda x, mol=mol: x.top==mol) 92 | 93 | ## # get the required types of nodes 94 | ## if searchType: 95 | ## if Klass == Atom and hasattr(mol_nodes, 'allAtoms'): 96 | ## mol_nodes = mol_nodes.allAtoms 97 | ## else: 98 | ## mol_nodes = mol_nodes.findType( Klass ) 99 | 100 | ## nodeSets.append( mol_nodes ) 101 | 102 | ## return molecules, nodeSets 103 | 104 | ## from MolKit.protein import ProteinSet, Protein,ResidueSet, Residue, ChainSet, Chain 105 | ## from MolKit.molecule import AtomSet, Atom, MoleculeSet, Molecule 106 | 107 | ## def getNodesByLevel(self, nodes, molecules,levelType=Protein, nodeType=None): 108 | ## """ ProteinSet, [nodeSet, nodeSet] <- getNodesByLevel(nodes) 109 | ## nodes can be either: a string, a TreeNode or a TreeNodeSet. 110 | ## This method returns a molecullevel set and for each level a TreeNodeSet 111 | ## of the nodes belonging to this molecule. 112 | ## 'nodeType' enables a desired type of nodes to be returned for each 113 | ## molecule 114 | ## """ 115 | ## import types 116 | ## # if it is a string, get a bunch of nodes from the string 117 | ## if type(nodes)==types.StringType: 118 | ## nodes = molecules.NodesFromName(nodes) 119 | 120 | ## assert issubclass(nodes.__class__, TreeNode) or \ 121 | ## issubclass(nodes.__class__, TreeNodeSet) 122 | 123 | ## # if nodes is a single TreeNode make it a singleton TreeNodeSet 124 | ## if issubclass(nodes.__class__, TreeNode): 125 | ## nodes = nodes.setClass([nodes]) 126 | 127 | ## if len(nodes)==0: 128 | ## levelSet = str(levelType)+'Set([])' 129 | ## return eval(levelSet), [] 130 | 131 | ## # catch the case when nodes is already a MoleculeSet 132 | ## if nodes.elementType == levelType: 133 | ## levelSets = nodes 134 | ## else: # get the set of molecules 135 | ## levelSets = nodes.findType(levelType).uniq() 136 | 137 | ## # build the set of nodes for each molecule 138 | ## nodeSets = [] 139 | 140 | ## # find out the type of the nodes we want to return 141 | ## searchType=0 142 | ## if nodeType is None: 143 | ## Klass = nodes.elementType # class of objects in that set 144 | ## else: 145 | ## assert issubclass(nodeType, TreeNode) 146 | ## Klass = nodeType 147 | ## if Klass != nodes.elementType: 148 | ## searchType=1 149 | 150 | ## for level in levelSets: 151 | ## # get set of nodes for this molecule 152 | ## mol_nodes = nodes.get(lambda x, mol=mol: x.top==mol) 153 | ## #level_nodes = nodes.get(lambda x, 154 | ## #nodes.get(lambda x, levelType = levelType, level = level: x.findType(levelType) # get the required types of nodes 155 | ## if searchType: 156 | ## if Klass == Atom and hasattr(mol_nodes, 'allAtoms'): 157 | ## mol_nodes = mol_nodes.allAtoms 158 | ## else: 159 | ## mol_nodes = mol_nodes.findType( Klass ) 160 | 161 | ## nodeSets.append( mol_nodes ) 162 | 163 | ## return molecules, nodeSets 164 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/data/__init__.py.bak: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # 3 | # Author: Michel F. SANNER, Sophie COON 4 | # 5 | # Copyright: M. Sanner TSRI 2000 6 | # 7 | ############################################################################# 8 | 9 | # 10 | #$Header: /mnt/raid/services/cvs/python/packages/share1.5/MolKit/data/__init__.py,v 1.1 2002/01/23 20:18:31 rhuey Exp $ 11 | # 12 | #$Id: __init__.py,v 1.1 2002/01/23 20:18:31 rhuey Exp $ 13 | # 14 | 15 | import string 16 | 17 | def Read(filename): 18 | from MolKit.pdbParser import PdbParser, PdbqParser,PdbqsParser, PQRParser 19 | from MolKit.mol2Parser import Mol2Parser 20 | ext = string.split(filename, '.') 21 | if ext[-1]=='pdb': 22 | parser = PdbParser(filename) 23 | 24 | elif ext[-1]=='pdbq': 25 | parser = PdbqParser(filename) 26 | 27 | elif ext[-1]=='pdbqs': 28 | parser = PdbqsParser(filename) 29 | 30 | elif ext[-1]=='pqr': 31 | parser = PQRParser(filename) 32 | 33 | elif ext[-1]=='mol2': 34 | parser = Mol2Parser(filename) 35 | 36 | else: 37 | print "File Format unknown can't parse it" 38 | return [] 39 | molecules = parser.parse() 40 | return molecules 41 | 42 | def WritePDB(filename,node): 43 | from MolKit.pdbWriter import PdbWriter 44 | writer = PdbWriter() 45 | writer.write(filename, node) 46 | 47 | 48 | ## def getNodesByMolecule(self, nodes, molecules,nodeType=None): 49 | ## """ moleculeSet, [nodeSet, nodeSet] <- getNodesByMolecule(nodes) 50 | ## nodes can be either: a string, a TreeNode or a TreeNodeSet. 51 | ## This method returns a molecule set and for each molecule a TreeNodeSet 52 | ## of the nodes belonging to this molecule. 53 | ## 'nodeType' enables a desired type of nodes to be returned for each 54 | ## molecule 55 | ## """ 56 | 57 | ## # if it is a string, get a bunch of nodes from the string 58 | ## if type(nodes)==types.StringType: 59 | ## nodes = molecules.NodesFromName(nodes) 60 | 61 | ## assert issubclass(nodes.__class__, TreeNode) or \ 62 | ## issubclass(nodes.__class__, TreeNodeSet) 63 | 64 | ## # if nodes is a single TreeNode make it a singleton TreeNodeSet 65 | ## if issubclass(nodes.__class__, TreeNode): 66 | ## nodes = nodes.setClass([nodes]) 67 | 68 | ## if len(nodes)==0: return MoleculeSet([]), [] 69 | 70 | ## # catch the case when nodes is already a MoleculeSet 71 | ## if nodes.elementType in [Molecule, Protein]: 72 | ## molecules = nodes 73 | ## else: # get the set of molecules 74 | ## molecules = nodes.top.uniq() 75 | 76 | ## # build the set of nodes for each molecule 77 | ## nodeSets = [] 78 | 79 | ## # find out the type of the nodes we want to return 80 | ## searchType=0 81 | ## if nodeType is None: 82 | ## Klass = nodes.elementType # class of objects in that set 83 | ## else: 84 | ## assert issubclass(nodeType, TreeNode) 85 | ## Klass = nodeType 86 | ## if Klass != nodes.elementType: 87 | ## searchType=1 88 | 89 | ## for mol in molecules: 90 | ## # get set of nodes for this molecule 91 | ## mol_nodes = nodes.get(lambda x, mol=mol: x.top==mol) 92 | 93 | ## # get the required types of nodes 94 | ## if searchType: 95 | ## if Klass == Atom and hasattr(mol_nodes, 'allAtoms'): 96 | ## mol_nodes = mol_nodes.allAtoms 97 | ## else: 98 | ## mol_nodes = mol_nodes.findType( Klass ) 99 | 100 | ## nodeSets.append( mol_nodes ) 101 | 102 | ## return molecules, nodeSets 103 | 104 | ## from MolKit.protein import ProteinSet, Protein,ResidueSet, Residue, ChainSet, Chain 105 | ## from MolKit.molecule import AtomSet, Atom, MoleculeSet, Molecule 106 | 107 | ## def getNodesByLevel(self, nodes, molecules,levelType=Protein, nodeType=None): 108 | ## """ ProteinSet, [nodeSet, nodeSet] <- getNodesByLevel(nodes) 109 | ## nodes can be either: a string, a TreeNode or a TreeNodeSet. 110 | ## This method returns a molecullevel set and for each level a TreeNodeSet 111 | ## of the nodes belonging to this molecule. 112 | ## 'nodeType' enables a desired type of nodes to be returned for each 113 | ## molecule 114 | ## """ 115 | ## import types 116 | ## # if it is a string, get a bunch of nodes from the string 117 | ## if type(nodes)==types.StringType: 118 | ## nodes = molecules.NodesFromName(nodes) 119 | 120 | ## assert issubclass(nodes.__class__, TreeNode) or \ 121 | ## issubclass(nodes.__class__, TreeNodeSet) 122 | 123 | ## # if nodes is a single TreeNode make it a singleton TreeNodeSet 124 | ## if issubclass(nodes.__class__, TreeNode): 125 | ## nodes = nodes.setClass([nodes]) 126 | 127 | ## if len(nodes)==0: 128 | ## levelSet = str(levelType)+'Set([])' 129 | ## return eval(levelSet), [] 130 | 131 | ## # catch the case when nodes is already a MoleculeSet 132 | ## if nodes.elementType == levelType: 133 | ## levelSets = nodes 134 | ## else: # get the set of molecules 135 | ## levelSets = nodes.findType(levelType).uniq() 136 | 137 | ## # build the set of nodes for each molecule 138 | ## nodeSets = [] 139 | 140 | ## # find out the type of the nodes we want to return 141 | ## searchType=0 142 | ## if nodeType is None: 143 | ## Klass = nodes.elementType # class of objects in that set 144 | ## else: 145 | ## assert issubclass(nodeType, TreeNode) 146 | ## Klass = nodeType 147 | ## if Klass != nodes.elementType: 148 | ## searchType=1 149 | 150 | ## for level in levelSets: 151 | ## # get set of nodes for this molecule 152 | ## mol_nodes = nodes.get(lambda x, mol=mol: x.top==mol) 153 | ## #level_nodes = nodes.get(lambda x, 154 | ## #nodes.get(lambda x, levelType = levelType, level = level: x.findType(levelType) # get the required types of nodes 155 | ## if searchType: 156 | ## if Klass == Atom and hasattr(mol_nodes, 'allAtoms'): 157 | ## mol_nodes = mol_nodes.allAtoms 158 | ## else: 159 | ## mol_nodes = mol_nodes.findType( Klass ) 160 | 161 | ## nodeSets.append( mol_nodes ) 162 | 163 | ## return molecules, nodeSets 164 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/data/nh2e.in: -------------------------------------------------------------------------------- 1 | 1 1 2 2 | db4.dat 3 | NH2 ENDING GROUP 4 | 5 | NHE INT 1 6 | CORRECT OMIT DU BEG 7 | 0.00000 8 | 1 DUMM DU M 0 -1 -2 0.0000 0.0000 0.0000 9 | 2 DUMM DU M 1 0 -1 1.0000 0.0000 0.0000 10 | 3 DUMM DU M 2 1 0 1.0000 90.0000 0.0000 11 | 4 N N M 3 2 1 1.3350 116.6000 180.0000 12 | 5 HN1 H E 4 3 2 1.0100 119.8000 0.0000 13 | 6 HN2 H E 4 3 2 1.0100 119.8000 180.0000 14 | 15 | CHARGE 16 | -0.46300 0.23150 0.23150 17 | 18 | IMPROPER 19 | -M HN1 N HN2 20 | 21 | DONE 22 | STOP 23 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/data/nh2e_dat.py: -------------------------------------------------------------------------------- 1 | nh2e_dat = { 2 | "filename":'nh2e.in', 3 | "NAMDBF":'db4.dat', 4 | "IDBGEN,IREST,ITYPF":['1', '1', '2'], 5 | "NHE": { "N":{'torsion': 180.0, 'tree': 'M', 'NC': 1, 'NB': 2, 'NA': 3, 'I': 4, 'angle': 116.6, 'blen': 1.335, 'charge': -0.463, 'type': 'N'}, 6 | "INTX,KFORM":['INT', '1'], 7 | "atNameList":['N', 'HN1', 'HN2'], 8 | "DUMM":[['1', 'DUMM', 'DU', 'M', '0', '-1', '-2', '0.0000', '0.0000', '0.0000'], ['2', 'DUMM', 'DU', 'M', '1', '0', '-1', '1.0000', '0.0000', '0.0000'], ['3', 'DUMM', 'DU', 'M', '2', '1', '0', '1.0000', '90.0000', '0.0000']], 9 | "IFIXC,IOMIT,ISYMDU,IPOS":['CORRECT', 'OMIT', 'DU', 'BEG'], 10 | "HN2":{'torsion': 180.0, 'tree': 'E', 'NC': 2, 'NB': 3, 'NA': 4, 'I': 6, 'angle': 119.8, 'blen': 1.01, 'charge': 0.2315, 'type': 'H'}, 11 | "impropTors":[['-M', 'HN1', 'N', 'HN2']], 12 | "CUT":['0.00000'], 13 | "HN1":{'torsion': 0.0, 'tree': 'E', 'NC': 2, 'NB': 3, 'NA': 4, 'I': 5, 'angle': 119.8, 'blen': 1.01, 'charge': 0.2315, 'type': 'H'}, 14 | "NAMRES":'NH2 ENDING GROUP', 15 | }, 16 | } -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/data/opls_nacl.in: -------------------------------------------------------------------------------- 1 | 1 1 3 2 | db4.dat 3 | Sodium Ion 4 | NA 5 | NA INT 1 6 | CORR OMIT DU BEG 7 | 0.000000 8 | 1 DUMM DU M 0 -1 -2 0.0000 0.0000 0.0000 0.000 9 | 2 DUMM DU M 1 0 -1 1.0000 0.0000 0.0000 0.000 10 | 3 DUMM DU M 2 1 0 1.0000 90.0000 0.0000 0.000 11 | 4 NA SO M 3 2 1 1.0000 90.0000 180.0000 1.000 12 | 13 | DONE 14 | Chloride Ion 15 | CL 16 | CL INT 1 17 | CORR OMIT DU BEG 18 | 0.000000 19 | 1 DUMM DU M 0 -1 -2 0.0000 0.0000 0.0000 0.000 20 | 2 DUMM DU M 1 0 -1 1.0000 0.0000 0.0000 0.000 21 | 3 DUMM DU M 2 1 0 1.0000 90.0000 0.0000 0.000 22 | 4 CL CL M 3 2 1 1.0000 90.0000 180.0000 -1.000 23 | 24 | DONE 25 | STOP 26 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/data/opls_nacl_dat.py: -------------------------------------------------------------------------------- 1 | opls_nacl_dat = { 2 | "CL": { "INTX,KFORM":['INT', '1'], 3 | "atNameList":['CL'], 4 | "DUMM":[['1', 'DUMM', 'DU', 'M', '0', '-1', '-2', '0.0000', '0.0000', '0.0000', '0.000'], ['2', 'DUMM', 'DU', 'M', '1', '0', '-1', '1.0000', '0.0000', '0.0000', '0.000'], ['3', 'DUMM', 'DU', 'M', '2', '1', '0', '1.0000', '90.0000', '0.0000', '0.000']], 5 | "IFIXC,IOMIT,ISYMDU,IPOS":['CORR', 'OMIT', 'DU', 'BEG'], 6 | "CL":{'torsion': 180.0, 'tree': 'M', 'NC': 1, 'NB': 2, 'NA': 3, 'I': 4, 'angle': 90.0, 'blen': 1.0, 'charge': -1.0, 'type': 'CL'}, 7 | "CUT":['0.000000'], 8 | "NAMRES":'Chloride Ion', 9 | }, 10 | "NAMDBF":'db4.dat', 11 | "filename":'opls_nacl.in', 12 | "NA": { "INTX,KFORM":['INT', '1'], 13 | "atNameList":['NA'], 14 | "DUMM":[['1', 'DUMM', 'DU', 'M', '0', '-1', '-2', '0.0000', '0.0000', '0.0000', '0.000'], ['2', 'DUMM', 'DU', 'M', '1', '0', '-1', '1.0000', '0.0000', '0.0000', '0.000'], ['3', 'DUMM', 'DU', 'M', '2', '1', '0', '1.0000', '90.0000', '0.0000', '0.000']], 15 | "NA":{'torsion': 180.0, 'tree': 'M', 'NC': 1, 'NB': 2, 'NA': 3, 'I': 4, 'angle': 90.0, 'blen': 1.0, 'charge': 1.0, 'type': 'SO'}, 16 | "IFIXC,IOMIT,ISYMDU,IPOS":['CORR', 'OMIT', 'DU', 'BEG'], 17 | "CUT":['0.000000'], 18 | "NAMRES":'Sodium Ion', 19 | }, 20 | "IDBGEN,IREST,ITYPF":['1', '1', '3'], 21 | } -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/data/rotamer.def: -------------------------------------------------------------------------------- 1 | # DO NOT edit this file unless you are aware of the details of Rotamer code 2 | # to add rotamer for non-standard amino acid, append the chi (X) angle 3 | # definition to the file. following the same format 4 | # 5 | # Yong Zhao 6 | # 7 | 8 | # format: 9 | # amino_acid_name a b c d X Y Z ... 10 | # 11 | # a,b,c,d are the four atom names that defines the dihedral angle. 12 | # X Y Z... etc are the names of atoms that will be moved by this rotation. 13 | 14 | # attention: the angles are ordered. (cooresponding to X1,X2, X3.. etc) 15 | # all data are seperated by (one or more) space/tab 16 | 17 | # ALA and GLY is not defined 18 | 19 | ARG N CA CB CG CG 20 | ARG CA CB CG CD CD 21 | ARG CB CG CD NE NE 22 | ARG CG CD NE CZ CZ NH1 NH2 23 | 24 | ASN N CA CB CG CG 25 | ASN CA CB CG ND2 OD1 ND2 26 | 27 | ASP N CA CB CG CG 28 | ASP CA CB CG OD1 OD1 OD2 29 | 30 | CYS N CA CB SG SG 31 | 32 | 33 | GLN N CA CB CG CG 34 | GLN CA CB CG CD CD 35 | GLN CB CG CD OE1 OE1 NE2 36 | 37 | GLU N CA CB CG CG 38 | GLU CA CB CG CD CD 39 | GLU CB CG CD OE1 OE1 OE2 40 | 41 | 42 | HIS N CA CB CG CG 43 | HIS CA CB CG ND1 NE1 CE1 NE2 CD2 44 | 45 | ILE N CA CB CG1 CG1 CG2 46 | ILE CA CB CG1 CD1 CD1 47 | 48 | 49 | LEU N CA CB CG CG 50 | LEU CA CB CG CD1 CD1 CD2 51 | 52 | LYS N CA CB CG CG 53 | LYS CA CB CG CD CD 54 | LYS CB CG CD CE CE 55 | LYS CG CD CE NZ NZ 56 | 57 | MET N CA CB CG CG 58 | MET CA CB CG SD SD 59 | MET CB CG SD CE CE 60 | 61 | 62 | 63 | PHE N CA CB CG CG 64 | PHE CA CB CG CD1 CD1 CD2 CE1 CE2 CZ 65 | 66 | 67 | PRO N CA CB CG CG 68 | PRO CA CB CG CD CD 69 | 70 | 71 | SER N CA CB OG OG 72 | 73 | THR N CA CB CG2 CG2 OG1 74 | 75 | TRP N CA CB CG CG 76 | TRP CA CB CG CD1 CD1 CD2 NE1 CE2 CE3 CZ2 CZ3 CH2 77 | 78 | TYR N CA CB CG CG 79 | TYR CA CB CG CD1 CD1 CD2 CE1 CE2 CZ OH 80 | 81 | 82 | VAL N CA CB CG1 CG1 CG2 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/introduction.py: -------------------------------------------------------------------------------- 1 | # 2 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/MolKit/introduction.py,v 1.1.1.1 2001/04/03 19:47:52 gillet Exp $ 3 | # 4 | # $Id: introduction.py,v 1.1.1.1 2001/04/03 19:47:52 gillet Exp $ 5 | # 6 | 7 | """This package contains a number of class to describe molecular entities such as Molecules, Molecular surface""" 8 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/mmcifWriter.py: -------------------------------------------------------------------------------- 1 | 2 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/MolKit/mmcifWriter.py,v 1.9 2006/04/25 22:05:20 sargis Exp $ 3 | # 4 | # $Id: mmcifWriter.py,v 1.9 2006/04/25 22:05:20 sargis Exp $ 5 | # 6 | 7 | from os.path import splitext, basename 8 | from string import split, strip, digits, lower, find 9 | from MolKit.moleculeWriter import MoleculeWriter 10 | from MolKit.pdbWriter import PdbWriter 11 | from MolKit.tree import TreeNode, TreeNodeSet 12 | #from MolKit import __MGLTOOLSVersion__ 13 | import os 14 | import sys 15 | 16 | class MMCIFWriter(MoleculeWriter): 17 | """Class to write data records from a molecule tree to a cif file.""" 18 | def write(self, filename, nodes): 19 | assert isinstance(nodes, TreeNode) or isinstance(nodes, TreeNodeSet) 20 | if isinstance(nodes, TreeNode): mol = nodes.top 21 | elif isinstance(nodes, TreeNodeSet): mol = nodes.top.uniq()[0] 22 | else: return 23 | 24 | Filename = "%s.cif"%(splitext(filename)[0]) 25 | file_out = open(Filename, 'w') 26 | file_out.write("data_"+mol.name+'\n') 27 | file_out.write("#\n") 28 | 29 | file_out.write("_software.name MGLTools\n") 30 | #file_out.write("_software.version " + __MGLTOOLSVersion__ + "\n") 31 | file_out.write("_software.contact_author Dr. Michel Sanner\n") 32 | file_out.write("_software.contact_author_email mgltools@scripps.edu\n") 33 | file_out.write("_software.location http://www.scripps.edu/~sanner/software\n") 34 | file_out.write("_software.language Python\n") 35 | file_out.write("_software.compiler_version " + sys.version.split()[0] + "\n") 36 | file_out.write("_software.os " + sys.platform + "\n") 37 | file_out.write("#\n_entry.id "+mol.name+"\n#\n") 38 | try: 39 | a,b,c = mol.cellLength 40 | file_out.write("_cell.length_a " + a + "\n") 41 | file_out.write("_cell.length_b " + b + "\n") 42 | file_out.write("_cell.length_c " + c + "\n") 43 | alpha,beta,gamma = mol.cellAngles 44 | file_out.write("_cell.angle_alpha " + alpha + "\n") 45 | file_out.write("_cell.angle_beta " + beta + "\n") 46 | file_out.write("_cell.angle_gamma " + gamma + "\n") 47 | file_out.write("_cell.Z_PDB " + mol.Zvalue + "\n") 48 | file_out.write("_symmetry.space_group_name_H-M " + mol.spaceGroup + "\n") 49 | except AttributeError: 50 | pass 51 | 52 | file_out.write("#\n") 53 | file_out.write("loop_\n") 54 | file_out.write("_atom_site.group_PDB\n") #1 55 | file_out.write("_atom_site.id\n") #2 56 | file_out.write("_atom_site.type_symbol\n") #3 57 | file_out.write("_atom_site.label_atom_id\n") #4 58 | file_out.write("_atom_site.label_comp_id\n") #5 59 | file_out.write("_atom_site.label_asym_id\n") #6 60 | file_out.write("_atom_site.label_seq_id\n") #7 61 | file_out.write("_atom_site.Cartn_x\n") #8 62 | file_out.write("_atom_site.Cartn_y\n") #9 63 | file_out.write("_atom_site.Cartn_z\n") #10 64 | file_out.write("_atom_site.occupancy\n") #11 65 | file_out.write("_atom_site.B_iso_or_equiv\n")#12 66 | 67 | Atoms = mol.allAtoms 68 | for Atom in Atoms: 69 | if Atom.hetatm == 0: 70 | file_out.write("ATOM") #1 71 | else: 72 | file_out.write("HETATM") 73 | file_out.write(" %6s"%Atom.number) #2 74 | file_out.write(" " + Atom.element) #3 75 | file_out.write(" %5s"%Atom.name) #4 76 | file_out.write(" " + Atom.parent.type) #5 77 | if Atom.parent.parent.name == ' ': 78 | file_out.write(" ?") #6 79 | else: 80 | file_out.write(" " + Atom.parent.parent.name) 81 | file_out.write(" %5d"%int(Atom.parent.number)) #7 82 | file_out.write(" %7.3f"%Atom._coords[0][0]) #8 83 | file_out.write(" %7.3f"%Atom._coords[0][1]) #9 84 | file_out.write(" %7.3f"%Atom._coords[0][2]) #10 85 | file_out.write(" %6.2f"%float(Atom.occupancy)) #11 86 | file_out.write(" %6.2f"%float(Atom.temperatureFactor)) #12 87 | file_out.write("\n") 88 | file_out.close() 89 | 90 | if __name__ == '__main__': 91 | from MolKit.mmcifParser import MMCIFParser 92 | parser = MMCIFParser( filename='Tests/Data/1CRN.cif' ) 93 | print("Reading molecule") 94 | mol = parser.parse() 95 | print("Done parsing") 96 | SS_Data = parser.parseSSData( mol ) 97 | print("Done parsing secondary structure") 98 | writer = MMCIFWriter() 99 | writer.write('Tests/Data/1CRN_.cif',mol) 100 | print("Done") 101 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/moleculeParser.py: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # 3 | # Author: Michel F. SANNER 4 | # 5 | # Copyright: M. Sanner TSRI 2000 6 | # 7 | ############################################################################# 8 | 9 | # 10 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/MolKit/moleculeParser.py,v 1.9.8.2 2017/02/08 21:49:34 forli Exp $ 11 | # 12 | # $Id: moleculeParser.py,v 1.9.8.2 2017/02/08 21:49:34 forli Exp $ 13 | # 14 | 15 | from MolKit.molecule import Atom 16 | import warnings, os 17 | from mglutil.util.misc import ensureFontCase 18 | 19 | # dict used to guess parser based on file extension 20 | parserToExt = {'PDB':'.pdb', 'PDBQ':'.pdbq', 21 | 'PDBQS':'.pdbqs', 'PDBQT':'.pdbqt', 22 | 'MOL2':'.mol2', 23 | 'PQR':'.pqr', 24 | 'GRO':'.gro', 25 | 'F2D':'.f2d', 26 | 'SDF':'.sdf', 27 | 'CIF':'.cif', 28 | } 29 | 30 | 31 | class MoleculeParser: 32 | def __init__(self, filename=None, allLines=None): 33 | """Supply the filename for reading by readFile, or 34 | supply the lines directly via allLines 35 | """ 36 | self.filename = str(filename) 37 | self.allLines = allLines #stores all lines from file 38 | 39 | 40 | def readFile(self): 41 | f = open(self.filename) 42 | self.allLines = f.readlines() 43 | if len(self.allLines)==1: 44 | # this file probably has \r instead or \n 45 | self.allLines = self.allLines[0].split('\r') 46 | warnings.warn('Only 1 line read from PDB file, splitting on \r') 47 | f.close() 48 | import string 49 | self.allLines = [x for x in self.allLines if x.strip()] 50 | 51 | 52 | 53 | def viewSource(self): 54 | import tkinter, Pmw 55 | root = tkinter.Toplevel() 56 | root.title(self.filename) 57 | self.st = Pmw.ScrolledText(root) 58 | self.st.pack(fill = 'both', expand=1) 59 | 60 | self.st._textbox.configure(bg='white', font=(ensureFontCase('Courier'), '10')) 61 | txt = '' 62 | for line in self.allLines: 63 | txt += ''.join(line) 64 | self.st.setvalue(txt) 65 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/moleculeWriter.py: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # 3 | # Author: Michel F. SANNER 4 | # 5 | # Copyright: M. Sanner TSRI 2000 6 | # 7 | ############################################################################# 8 | 9 | # 10 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/MolKit/moleculeWriter.py,v 1.1.1.1 2001/04/03 19:47:52 gillet Exp $ 11 | # 12 | # $Id: moleculeWriter.py,v 1.1.1.1 2001/04/03 19:47:52 gillet Exp $ 13 | # 14 | 15 | class MoleculeWriter: 16 | 17 | pass 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/oxtBuilder.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # 3 | # Author: Ruth Huey 4 | # 5 | # Copyright: M. Sanner TSRI 2004 6 | # 7 | ############################################################################# 8 | 9 | # 10 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/MolKit/oxtBuilder.py,v 1.1 2005/09/15 16:02:04 rhuey Exp $ 11 | # 12 | # $Id: oxtBuilder.py,v 1.1 2005/09/15 16:02:04 rhuey Exp $ 13 | # 14 | 15 | """ 16 | This module implements the OxtBuilder class which adds an oxygen atom to 17 | a specific carbon atom, presumably in the c-terminus residue. This class 18 | assumes that bonds have been previously built in the molecule. 19 | 20 | """ 21 | 22 | from MolKit.molecule import Atom, AtomSet, Bond 23 | from PyBabel.atomTypes import AtomHybridization 24 | from PyBabel.addh import AddHydrogens 25 | 26 | 27 | class OxtBuilder: 28 | """Base Class for adding an oxygen atom to a carbon atom. 29 | NOTE: molecule must have bonds built between atoms 30 | """ 31 | 32 | 33 | def __init__(self): 34 | self.addh = AddHydrogens() 35 | 36 | 37 | def add_oxt(self, catom): 38 | if catom.element!='C': 39 | return 40 | mol = catom.top 41 | ##check for bonds 42 | #if len(mol.allAtoms.bonds[0])==0: 43 | # mol.buildBondsByDistance() 44 | #check whether residue already has OXT 45 | res = catom.parent 46 | if 'OXT' in res.atoms.name: 47 | print('not adding OXT to ',res.full_name(),'\n', 'it already has an OXT atom') 48 | return 49 | #check whether catom has a hydrogen to delete 50 | hatoms = catom.parent.atoms.get(lambda x: x.name=='HC') 51 | if len(hatoms): 52 | hatom = hatoms[0] 53 | #check for hbonds 54 | if hasattr(hatom, 'hbonds'): 55 | #remove hbonds 56 | for b in hatom.hbonds: 57 | atList = [b.donAt, b.accAt] 58 | if b.hAt is not None: 59 | atList.append(b.hAt) 60 | for at in atList: 61 | #hbonds might already be gone 62 | if not hasattr(at, 'hbonds'): 63 | continue 64 | okhbnds = [] 65 | for hb in at.hbonds: 66 | if hb!=b: 67 | okhbnds.append(hb) 68 | if len(okhbnds): 69 | at.hbonds = okhbnds 70 | else: 71 | delattr(at, 'hbonds') 72 | #remove covalent bonds 73 | for b in hatom.bonds: 74 | at2 = b.atom1 75 | if at2 == hatom: at2 = b.atom2 76 | at2.bonds.remove(b) 77 | hatom.parent.remove(hatom, cleanup=1) 78 | 79 | #have to type atoms before call to add_sp2_hydrogen: 80 | if not hasattr(catom,'babel_type'): 81 | print('catom has no babel_type: calling typeAtoms') 82 | #self.warningMsg(msg) 83 | #typeAtoms does whole molecule 84 | babel = AtomHybridization() 85 | babel.assignHybridization(mol.allAtoms) 86 | 87 | #NB: bond_length 1.28 measured from OXT-C bond in 1crn 88 | tup1 = self.addh.add_sp2_hydrogen(catom, 1.28) 89 | res = catom.parent 90 | 91 | # find where to insert H atom 92 | childIndex = res.children.index(catom)+1 93 | name = 'OXT' 94 | 95 | # create the OXT atom object 96 | atom = Atom(name, res, top=mol, 97 | childIndex=childIndex, assignUniqIndex=0) 98 | 99 | # set atoms attributes 100 | atom._coords = [ tup1[0][0] ] 101 | if hasattr(catom, 'segID'): atom.segID = catom.segID 102 | atom.hetatm = 0 103 | atom.alternate = [] 104 | atom.element = 'O' 105 | atom.occupancy = 1.0 106 | atom.conformation = 0 107 | atom.temperatureFactor = 0.0 108 | atom.babel_atomic_number = 8 109 | atom.babel_type = 'O-' 110 | atom.babel_organic = 1 111 | 112 | # create the Bond object bonding Hatom to heavyAtom 113 | bond = Bond( catom, atom, bondOrder=2) 114 | 115 | # create the color entries for all geometries 116 | # available for the other oxygen atom attached to 'C' 117 | oatom = res.atoms.get(lambda x: x.name=='O')[0] 118 | if oatom is not None: 119 | for key, value in list(oatom.colors.items()): 120 | atom.colors[key] = value 121 | #atom.opacities[key] = oatom.opacities[key] 122 | 123 | # update the allAtoms set in the molecule 124 | mol.allAtoms = mol.chains.residues.atoms 125 | 126 | # update numbers of allAtoms 127 | fst = mol.allAtoms[0].number 128 | mol.allAtoms.number = list(range(fst, len(mol.allAtoms)+fst)) 129 | 130 | # update _uniqIndex of this residues atoms 131 | res.assignUniqIndex() 132 | #return AtomSet([atom]) 133 | return atom 134 | 135 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/pqrWriter.py: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # 3 | # Author: Michel F. SANNER 4 | # 5 | # Copyright: M. Sanner TSRI 2000 6 | # 7 | ############################################################################# 8 | 9 | from MolKit.moleculeWriter import MoleculeWriter 10 | from MolKit.protein import Protein, Chain, ChainSet 11 | from MolKit.molecule import Atom 12 | from MolKit.tree import TreeNode, TreeNodeSet 13 | import os 14 | 15 | class PqrWriter(MoleculeWriter): 16 | """Class to write data records from a molecule tree to a prq file.""" 17 | 18 | 19 | def write(self, fileName, node, sort=None): 20 | """Takes a filename and TreeNode or TreeNodeSet instance. If no 21 | filename extension is provided, a '.pqr' extension is added. For 22 | the node or set, the records for the whole protein are written, 23 | but ATOM records are written only for those atoms contained 24 | within and below that node or set. 25 | if a sort function is specified, the list of nodes is sorted 26 | using this function. This function has to return -1, 0, 1 if 27 | the first argument is smaller, equal or larger then the second 28 | argument""" 29 | 30 | self.numCoord = 0 31 | filename = fileName 32 | root_ext = os.path.splitext('%s' %filename) 33 | if root_ext[1]=='': 34 | filename = '%s.pqr' %fileName 35 | assert isinstance(node, TreeNode) or isinstance(node, TreeNodeSet) 36 | if isinstance(node, TreeNode): 37 | mol = node.top 38 | elif isinstance(node, TreeNodeSet): 39 | mol = node.top.uniq()[0] 40 | else: 41 | return 42 | 43 | file = open('%s' % filename, 'w') 44 | if sort: 45 | node.sort(sort) 46 | self.write_AtomSet(file, node) 47 | file.close() 48 | 49 | 50 | 51 | def write_atom(self, f, atm): 52 | """Takes a file object and an Atom instance. Writes the atom 53 | record to the file.""" 54 | 55 | spaceStr = " " 56 | #columns1-6 57 | if atm.hetatm==0: f.write('ATOM ') 58 | else: f.write('HETATM') 59 | #columns 7-11 + A SPACE 60 | f.write('%5i ' % atm.number) 61 | #columns 13-16 62 | spaceChar = None 63 | 64 | if len(atm.name)==4: 65 | if atm.element=='H': 66 | #name = atm.name[-1]+atm.name[1:] 67 | name = atm.name[-1]+atm.name[:-1] 68 | f.write('%-4.4s' % name) 69 | else: 70 | name = atm.name 71 | f.write('%4.4s' % name) 72 | elif len(atm.element)==2: #else of if(atm.name)==4 73 | f.write('%-4.4s' % atm.element) 74 | else: 75 | f.write(' %-3s' % atm.name) 76 | 77 | #columns 17 78 | if not spaceChar: 79 | f.write('%1.1s' %spaceStr) 80 | else: 81 | f.write('%1.1s' %spaceChar[-1]) 82 | 83 | #columns 18-20 SPACE 22 84 | if hasattr(atm, 'parent') and hasattr(atm.parent, 'type'): 85 | f.write('%3.3s ' %atm.parent.type) 86 | # no chain ID 87 | f.write('%1.1s' %spaceStr) 88 | ## if hasattr(atm.parent, 'parent') and hasattr(atm.parent.parent, 'id'): 89 | ## f.write('%1.1s' %atm.parent.parent.id) 90 | ## else: 91 | ## f.write('%1.1s' %spaceStr) 92 | else: 93 | f.write('%5.5s' %spaceStr) 94 | 95 | #columns 23-26 96 | if hasattr(atm.parent, 'number'): 97 | f.write('%4.4s' % atm.parent.number) 98 | else: 99 | f.write('%4.4s' % spaceStr) 100 | #columns 27 plus 3 SPACES 101 | if hasattr(atm.parent, 'icode'): 102 | z=atm.parent.icode+' ' 103 | else: 104 | z=" " 105 | f.write('%4.4s' %z) 106 | #columns 31-38,39-46, 47-54 107 | for i in atm.coords: 108 | f.write('%8.3f' %i) 109 | 110 | f.write('%8.3f' %atm.charge) 111 | if hasattr(atm, 'pqrRadius'): 112 | f.write('%8.3f' %atm.pqrRadius) 113 | else: 114 | f.write('%8.3f' %atm.radius) 115 | 116 | f.write('\n') 117 | 118 | 119 | def write_AtomSet(self, file, node): 120 | """Takes a file object and a TreeNode or TreeNodeSet instance. 121 | For each Atom in node, write_AtomSet calls method write_atom. 122 | If node is a Chain or higher, write_AtomSet calls write_TER in 123 | between chains or at the end of a chain.""" 124 | 125 | if isinstance(node, Protein) or isinstance(node,Chain) or \ 126 | isinstance(node,ChainSet): 127 | 128 | chains = node.findType(Chain) 129 | for c in chains: 130 | atmset = c.findType(Atom) 131 | try: 132 | atmset.charge 133 | except: 134 | print('ERROR: atoms with missing charge found') 135 | return 'Error' 136 | 137 | try: 138 | atmset.radius 139 | except: 140 | print('ERROR: atoms with missing radius found') 141 | return 'Error' 142 | 143 | for a in atmset: 144 | self.write_atom(file, a) 145 | self.numCoord = self.numCoord + 1 146 | self.write_TER(file, atmset[-1]) 147 | self.numTer = self.numTer + 1 148 | else: 149 | atmset = node.findType(Atom) 150 | try: 151 | atmset.charge 152 | except: 153 | print('ERROR: atoms with missing charge found') 154 | return 'Error' 155 | try: 156 | atmset.radius 157 | except: 158 | print('ERROR: atoms with missing radius found') 159 | return 'Error' 160 | 161 | for a in atmset: 162 | self.write_atom(file, a) 163 | self.numCoord = self.numCoord + 1 164 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/MolKit/sets.py: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # 3 | # Authors: Michel F. SANNER, Ruth Huey 4 | # 5 | # Copyright: M. Sanner TSRI 2005 6 | # 7 | ############################################################################# 8 | # 9 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/MolKit/sets.py,v 1.2 2006/06/12 18:28:35 sargis Exp $ 10 | # 11 | # 12 | # 13 | # 14 | # 15 | 16 | from .tree import TreeNodeSet 17 | import types 18 | 19 | class Sets(dict): 20 | """ 21 | Object used to manage a collection of explicit sets of TreeNodes 22 | """ 23 | 24 | def add(self, name, set, overwrite=True): 25 | assert isinstance(set, TreeNodeSet) 26 | assert type(name) in (str,) 27 | 28 | if not overwrite: 29 | assert name not in list(self.keys()) 30 | self[name] = set 31 | 32 | 33 | def remove(self, name): 34 | # remove a set by name. Silently ignore non existing sets but returns 35 | # true when a set gets deleted, else returns False 36 | if name in list(self.keys()): 37 | del self[name] 38 | return True 39 | return False 40 | 41 | 42 | def removeByInstance(self, set): 43 | # remove a set that is specified by a TreeNodeSet. 44 | # Silently ignore non existing sets but returns 45 | # true when a set gets deleted, else returns False 46 | for n,s in list(self.items()): 47 | if s==set: 48 | del self[n] 49 | return True 50 | return False 51 | 52 | 53 | def get(self, stype=None): 54 | # return a dict of sets optionally restricted to a user specified type 55 | # if stype is specified it has to be a subclass of TreeNodeSet 56 | if stype is None: 57 | return self 58 | else: # select the sets of a given type 59 | assert issubclass(stype, TreeNodeSet) 60 | result = {} 61 | for name,set in list(self.items()): 62 | if isinstance(set, stype): 63 | result[name] = set 64 | return result 65 | 66 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/PyBabel/CVS/Entries: -------------------------------------------------------------------------------- 1 | /.packager.py/1.11/Thu Dec 18 21:52:48 2003//Trc-1-5-7 2 | /LICENSE/1.1/Thu Jul 3 20:46:37 2008//Trc-1-5-7 3 | /RELNOTES/1.3/Mon Dec 12 02:06:00 2005//Trc-1-5-7 4 | /__init__.py/1.10/Wed Mar 15 00:45:52 2006//Trc-1-5-7 5 | /addh.py/1.6/Thu Oct 11 17:43:48 2007//Trc-1-5-7 6 | /aromatic.py/1.3/Sat Nov 15 00:14:40 2008//Trc-1-5-7 7 | /atomTypes.py/1.6/Fri Oct 19 16:09:49 2012//Trc-1-5-7 8 | /babelAtomTypes.py/1.1.1.1/Tue Apr 3 19:47:47 2001//Trc-1-5-7 9 | /babelElements.py/1.2/Wed Sep 11 18:15:15 2002//Trc-1-5-7 10 | /bo.py/1.4/Tue Oct 22 23:11:38 2002//Trc-1-5-7 11 | /cycle.py/1.8/Thu Sep 4 23:53:56 2003//Trc-1-5-7 12 | /gasteiger.py/1.8/Fri Sep 2 18:41:39 2011//Trc-1-5-7 13 | /source.list/1.1.1.1/Tue Apr 3 19:47:47 2001//Trc-1-5-7 14 | /tools.py/1.1.1.1/Tue Apr 3 19:47:47 2001//Trc-1-5-7 15 | /util.py/1.3/Fri Oct 29 17:05:26 2010//Trc-1-5-7 16 | D 17 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/PyBabel/CVS/Entries.Log: -------------------------------------------------------------------------------- 1 | A D/Tests//// 2 | A D/regression//// 3 | A D/testdir//// 4 | R D/testdir//// 5 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/PyBabel/CVS/Repository: -------------------------------------------------------------------------------- 1 | python/packages/share1.5/PyBabel 2 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/PyBabel/CVS/Root: -------------------------------------------------------------------------------- 1 | :pserver:anonymous@orca.scripps.edu:/mnt/raid/services/cvs 2 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/PyBabel/CVS/Tag: -------------------------------------------------------------------------------- 1 | Trc-1-5-7 2 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/PyBabel/LICENSE: -------------------------------------------------------------------------------- 1 | This software is copyrighted by Michel F. Sanner (sanner@scripps.edu) and TSRI. 2 | The following terms apply to all files associated with the software 3 | unless explicitly disclaimed in individual files. 4 | 5 | MGLTOOLS SOFTWARE LICENSE AGREEMENT. 6 | 7 | 1. Grant Of Limited License; Software Use Restrictions. The programs 8 | received by you will be used only for NON COMMERCIAL purposes. 9 | This license is issued to you as an individual. 10 | 11 | For COMMERCIAL use done with the software please contact Michel F. 12 | Sanner for details about commercial usage license agreements. 13 | 14 | For any question regarding license agreements, please contact 15 | Michel Sanner: 16 | TSRI, Molecular Biology Department, TCP 26, 17 | 10550 North Torrey Pines Road, La Jolla, CA 92037 18 | sanner@scripps.edu 19 | tel (858) 784-7742 20 | fax (858) 784-2341 21 | 22 | 2. COMMERCIAL USAGE is defined as revenues generating activities. These 23 | include using this software for consulting activities and selling 24 | applications built on top of, or using this software. Scientific 25 | research in an academic environment and teaching are considered 26 | NON COMMERCIAL. 27 | 28 | 3. Copying Restrictions. You will not sell or otherwise distribute commercially 29 | these programs or derivatives to any other party, whether with or without 30 | consideration. 31 | 32 | 4. Ownership of Software. You will not obtain, and will not attempt to 33 | obtain copyright coverage thereon without the express purpose written 34 | consent of The Scripps Research Institute and Dr. Sanner. 35 | 36 | 5. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY 37 | FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 38 | ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY 39 | DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE 40 | POSSIBILITY OF SUCH DAMAGE. 41 | 42 | 6. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, 43 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, 44 | FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE 45 | IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE 46 | NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 47 | MODIFICATIONS. 48 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/PyBabel/RELNOTES: -------------------------------------------------------------------------------- 1 | ============================================================================== 2 | Python-based Molecular Viewer Release Notes: 3 | ============================================================================== 4 | 5 | Release rel 1.4alpha1(December 2005) 6 | _____________________________________________________________________________ 7 | What's new since rel 1.3alpha2: 8 | ------------------------------ 9 | Bug Fixes since rel 1.3alpha2: 10 | ----------------------------- 11 | changes after 1.3alpha2: 12 | ----------------------- 13 | *previously get_atomic_number broke on MG: corrected in get_atomic_number method which checked that the constructed "_name" was a key in the babel_elements dictionary but then tried to retrieve the value for "name". 14 | 15 | Release rel 1.2beta1 (12/15/2003) 16 | _____________________________________________________________________________ 17 | 18 | What's new since rel 1.2alpha (09/18/2003): 19 | 20 | Bug Fixes since rel 1.2alpha (09/18/2003): 21 | 22 | Changes since rel 1.2alpha (09/18/2003): 23 | 24 | Known Issues: 25 | 26 | Backwards INCOMPATIBLE Changes since rel 1.2alpha (09/18/2003): 27 | 28 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/PyBabel/source.list: -------------------------------------------------------------------------------- 1 | SOURCE= ./__init__.py ./atomTypes.py ./cycle.py ./bo.py ./aromatic.py \ 2 | ./addh.py ./gasteiger.py ./util.py ./tools.py ./babelAtomTypes.py \ 3 | ./babelElements.py 4 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/PyBabel/tools.py: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # 3 | # Author: Michel F. SANNER 4 | # Reimplemented from Babel v1.6 from Pat Walters and Math Stahl 5 | # 6 | # Copyright: M. Sanner TSRI 2000 7 | # 8 | ############################################################################# 9 | # 10 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/PyBabel/tools.py,v 1.1.1.1 2001/04/03 19:47:47 gillet Exp $ 11 | # 12 | # $Id: tools.py,v 1.1.1.1 2001/04/03 19:47:47 gillet Exp $ 13 | # 14 | # 15 | # 16 | 17 | import string 18 | 19 | def read_element_table(filename): 20 | """void <- read_element_table(filename) 21 | populates the elementsTable dictionary from the a given file. 22 | the file provides: 23 | line number, element string, cov_rad, bond_ord_rad, vdw_rad, bs_rad, 24 | max_bonds, red, green, blue 25 | """ 26 | f = open(filename) 27 | lines = f.readlines() 28 | f.close() 29 | elemTable = {} 30 | for i in range(len(lines)): 31 | dd = lines[i].split() 32 | elemTable[dd[1]] = { 'num':i, 33 | 'cov_rad':float(dd[2]), 34 | 'bond_ord_rad':float(dd[3]), 35 | 'vdw_rad':float(dd[4]), 36 | 'bs_rad':float(dd[5]), 37 | 'max_bonds':int(dd[6]), 38 | 'rgb': (float(dd[7]),float(dd[8]),float(dd[9])) 39 | } 40 | return elemTable 41 | 42 | 43 | def writeElementTableAsPythonCode(elemTab, inFileName, outFileName): 44 | """write elemTable as a python dictionary that can be imported""" 45 | 46 | f = open(outFileName,'w') 47 | f.write("# File generated from %s\n#\n"%inFileName) 48 | f.write("babel_elements = {\n") 49 | for k,v in list(elemTab.items()): 50 | f.write(" '%s': %s, \n" % (k,str(v))) 51 | f.write('}\n#END\n'); 52 | f.close() 53 | 54 | 55 | def read_types_table(filename): 56 | with open(filename) as f: 57 | typestab = {} 58 | nrow, ncol = map(int, f.readline().split()) 59 | typeFormats = f.readline().split() 60 | 61 | for t in typeFormats: 62 | typestab[t] = [] 63 | 64 | for _ in range(nrow - 1): 65 | typeNames = f.readline().split() 66 | for j in range(ncol): 67 | typestab[typeFormats[j]].append(typeNames[j]) 68 | 69 | return typestab 70 | 71 | 72 | def writeTypesTableAsPythonCode(typestab, inFileName, outFileName): 73 | """write typestab as a python dictionary that can be imported""" 74 | 75 | f = open(outFileName,'w') 76 | f.write("# File generated from %s\n#\n"%inFileName) 77 | f.write("babel_types = {\n") 78 | for k,v in list(typestab.items()): 79 | f.write(" '%s': %s, \n" % (k,str(v))) 80 | f.write('}\n#END\n'); 81 | f.close() 82 | 83 | 84 | if __name__ == '__main__': 85 | # write tables 86 | et = read_element_table('element.lis') 87 | writeElementTableAsPythonCode(et, 'element.lis', 'babelElements.py') 88 | 89 | tt = read_types_table('types.lis') 90 | writeTypesTableAsPythonCode(tt, 'types.lis', 'babelAtomTypes.py') 91 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/PyBabel/util.py: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # 3 | # Author: Michel F. SANNER 4 | # Reimplemented from Babel v1.6 from Pat Walters and Math Stahl 5 | # 6 | # Copyright: M. Sanner TSRI 2000 7 | # 8 | ############################################################################# 9 | 10 | """ 11 | This file defines constants and a few functions used throughout the package 12 | 13 | 14 | reimplmentation of Babel1.6 in Python by Michel Sanner April 2000 15 | Original code by W. Patrick Walters and Matthew T. Stahl 16 | """ 17 | 18 | # 19 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/PyBabel/util.py,v 1.3 2010/10/29 17:05:26 sargis Exp $ 20 | # 21 | # $Id: util.py,v 1.3 2010/10/29 17:05:26 sargis Exp $ 22 | # 23 | 24 | 25 | import math 26 | 27 | RAD_TO_DEG = 180.0/math.pi 28 | 29 | 30 | def distance(a, b): 31 | """float <- distance(a,b) returns the distance between 3D points a and b""" 32 | 33 | dx = b[0]-a[0] 34 | dy = b[1]-a[1] 35 | dz = b[2]-a[2] 36 | return math.sqrt( dx*dx + dy*dy +dz*dz) 37 | 38 | 39 | def bond_angle(a, b, c): 40 | """ 41 | float <- bond_angle(a, b, c) 42 | returns the angle in degrees between 3D pts a,b,c 43 | """ 44 | 45 | dist = distance(a,b) * distance(b,c) 46 | if dist == 0: # SD 2010 - http://mgl.scripps.edu/forum/viewtopic.php?f=11&t=245&p=1882 47 | raise ZeroDivisionError("Input used:", a, b, c) 48 | 49 | cos_theta = ( (a[0] - b[0]) * (c[0] - b[0]) + 50 | (a[1] - b[1]) * (c[1] - b[1]) + 51 | (a[2] - b[2]) * (c[2] - b[2]) ) / dist 52 | if cos_theta + 1.0 < 0.0001: angle = 180.0 53 | else: angle = (math.acos(cos_theta)) * RAD_TO_DEG 54 | return angle 55 | 56 | 57 | def torsion_angle(c1, c2, c3, c4): 58 | """ 59 | float <- torsion_angle(a, b, c, d) 60 | returns the torsion angle in degrees between 3D pts a,b,c,d 61 | """ 62 | 63 | v1 = (c1[0]-c2[0], c1[1]-c2[1], c1[2]-c2[2]) 64 | v2 = (c2[0]-c3[0], c2[1]-c3[1], c2[2]-c3[2]) 65 | v3 = (c3[0]-c4[0], c3[1]-c4[1], c3[2]-c4[2]) 66 | 67 | p = (v2[1]*v1[2] - v1[1]*v2[2], 68 | v1[0]*v2[2] - v2[0]*v1[2], 69 | v2[0]*v1[1] - v1[0]*v2[1]) 70 | 71 | q = (v3[1]*v2[2] - v2[1]*v3[2], 72 | v2[0]*v3[2] - v3[0]*v2[2], 73 | v3[0]*v2[1] - v2[0]*v3[1]) 74 | 75 | n = 1.0 / math.sqrt( p[0]*p[0] + p[1]*p[1] + p[2]*p[2] ) 76 | p = (p[0]*n, p[1]*n, p[2]*n ) 77 | 78 | n = 1.0 / math.sqrt( q[0]*q[0] + q[1]*q[1] + q[2]*q[2] ) 79 | q = (q[0]*n, q[1]*n, q[2]*n ) 80 | 81 | xtheta = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] 82 | 83 | if xtheta > 1.0: xtheta = 1.0 84 | if xtheta < -1.0: xtheta = -1.0 85 | theta = math.acos(xtheta) * 57.29578 86 | absth = math.fabs(theta) 87 | 88 | if absth < 0.001: 89 | return 0.0 90 | elif math.fabs(absth - 180.0) < 0.001: 91 | return 180.0 92 | 93 | s = v1[0]*q[0] + v1[1]*q[1] + v1[2]*q[2] 94 | if s < 0.0: 95 | theta = 360.0 - theta 96 | 97 | if theta > 180.0: 98 | theta = theta - 360.0 99 | 100 | return theta 101 | 102 | 103 | def vec3(a, b, norm=1.0): 104 | """ 105 | x,y,z <- vec3(a, b, norm=1.0) 106 | returns the vector a, b scale to norm 107 | """ 108 | dx = b[0]-a[0] 109 | dy = b[1]-a[1] 110 | dz = b[2]-a[2] 111 | l = norm / math.sqrt( dx*dx + dy*dy +dz*dz) 112 | return [dx*l, dy*l, dz*l] 113 | 114 | 115 | def determinant_3x3(m): 116 | """ 117 | float <- determinant_3x3(m) 118 | returns the determinant of the 3x3 matrix m 119 | """ 120 | x = m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) 121 | y = m[1][0] * (m[2][1] * m[0][2] - m[0][1] * m[2][2]) 122 | z = m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]) 123 | return (x + y + z) 124 | 125 | 126 | def invert_3x3(m): 127 | """ 128 | matrix3x3 <- invert_3x3(m) 129 | returns the inverse of a 3x3 matrix 130 | """ 131 | 132 | det = determinant_3x3(m) 133 | if (det != 0.0): 134 | t = [ [0,0,0], [0,0,0], [0,0,0] ] 135 | det = 1.0/det 136 | 137 | t[0][0] = m[1][1]*m[2][2] - m[2][1]*m[1][2] 138 | t[0][1] = m[2][1]*m[0][2] - m[0][1]*m[2][2] 139 | t[0][2] = m[0][1]*m[1][2] - m[1][1]*m[0][2] 140 | t[1][0] = m[1][2]*m[2][0] - m[2][2]*m[1][0] 141 | t[1][1] = m[2][2]*m[0][0] - m[0][2]*m[2][0] 142 | t[1][2] = m[0][2]*m[1][0] - m[1][2]*m[0][0] 143 | t[2][0] = m[1][0]*m[2][1] - m[2][0]*m[1][1] 144 | t[2][1] = m[2][0]*m[0][1] - m[0][0]*m[2][1] 145 | t[2][2] = m[0][0]*m[1][1] - m[1][0]*m[0][1] 146 | 147 | m[0][0] = t[0][0]*det 148 | m[0][1] = t[0][1]*det 149 | m[0][2] = t[0][2]*det 150 | m[1][0] = t[1][0]*det 151 | m[1][1] = t[1][1]*det 152 | m[1][2] = t[1][2]*det 153 | m[2][0] = t[2][0]*det 154 | m[2][1] = t[2][1]*det 155 | m[2][2] = t[2][2]*det 156 | return m 157 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/ResultParser.py: -------------------------------------------------------------------------------- 1 | # 2 | # Last modified on Mon Mar 4 14:35:36 PST 2002 by lindy 3 | # 4 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/AutoDockTools/ResultParser.py,v 1.3 2009/01/09 19:53:49 rhuey Exp $ 5 | # 6 | 7 | 8 | 9 | 10 | class ResultParser: 11 | """Base class of result parsers. Supply your own parseline 12 | function which appends a conformation dictionary to self.clist 13 | """ 14 | def __init__(self): 15 | self.clist = [] 16 | 17 | # add more keywords in subclass if you like 18 | keywords = [ 19 | 'cluster', # number of cluster 20 | 'cluster_rank', # rank within cluster 21 | 'rmsd_ref', # distance to reference structure 22 | 'rmsd_seed', # distance to lowest energy conf. in cluster 23 | 'binding_energy', # estimated free energy of binding 24 | 'docking_energy', # final docked energy 25 | 'internal_energy', 26 | 'trn_x', # translation x, y, z 27 | 'trn_y', 28 | 'trn_z', 29 | 'qtn_nx', # quaternion unit vector x, y, z 30 | 'qtn_ny', 31 | 'qtn_nz', 32 | 'qtn_ang_deg', # quaternion rotation angle 33 | 'num_torsions', 34 | 'torsion_values', 35 | 'rseed1', # the random number seeds for this conformation 36 | 'rseed2', 37 | ] 38 | 39 | def parse(self, filename): 40 | """ 41 | """ 42 | file_ptr = open(filename) 43 | 44 | self.clist = [] 45 | for line in file_ptr.readlines(): 46 | self.parseline(line) 47 | file_ptr.close() 48 | 49 | self.filename = filename 50 | 51 | return self.clist 52 | 53 | 54 | def parseline(self, line): 55 | """over ride me""" 56 | pass 57 | 58 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MatthijsHak/MetalDock/73a52ccf1bd1a8d199f80405ee9da70135c7cda6/src/external/AutoDockTools/__init__.py -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/CVS/Entries: -------------------------------------------------------------------------------- 1 | /TensorModule.py/1.3.12.1/Thu Feb 11 23:15:05 2016//Trc-1-5-7 2 | /VectorModule.py/1.3.12.1/Thu Feb 11 23:15:05 2016//Trc-1-5-7 3 | /__init__.py/1.4.12.2/Wed Mar 2 23:29:10 2016//Trc-1-5-7 4 | /crystal.py/1.4.8.1/Thu Feb 11 19:04:10 2016//Trc-1-5-7 5 | /gridDescriptor.py/1.1.26.1/Thu Feb 11 23:15:05 2016//Trc-1-5-7 6 | /julie12019854k.rot/1.1/Thu Mar 18 02:41:37 2004//Trc-1-5-7 7 | /kinematics.py/1.16.12.1/Thu Feb 11 19:04:10 2016//Trc-1-5-7 8 | /kinematicstest.py/1.8.12.1/Thu Feb 11 19:04:10 2016//Trc-1-5-7 9 | /kmeansClustering.py/1.1/Sat Sep 11 18:45:49 2010//Trc-1-5-7 10 | /munkres.py/1.2.4.1/Wed Aug 26 18:54:41 2015//Trc-1-5-7 11 | /munkresLICENSE/1.2.4.1/Wed Aug 26 18:54:41 2015//Trc-1-5-7 12 | /ncoords.py/1.2.12.1/Thu Feb 11 19:04:10 2016//Trc-1-5-7 13 | /ncoordstest.py/1.2.12.1/Thu Feb 11 19:04:10 2016//Trc-1-5-7 14 | /rigidFit.py/1.9.12.1/Thu Feb 11 23:15:05 2016//Trc-1-5-7 15 | /rmsd.py/1.6.12.2/Thu Feb 11 23:15:05 2016//Trc-1-5-7 16 | /rmsdtest.py/1.4.12.1/Thu Feb 11 23:15:05 2016//Trc-1-5-7 17 | /rotax.py/1.23.12.1/Thu Feb 11 23:15:05 2016//Trc-1-5-7 18 | /statetocoords.py/1.11.10.1/Thu Feb 11 23:15:05 2016//Trc-1-5-7 19 | /statetocoordstest.py/1.3.12.1/Thu Feb 11 23:15:05 2016//Trc-1-5-7 20 | /stats.py/1.5/Mon Jul 30 18:41:21 2007//Trc-1-5-7 21 | /torsion.py/1.2.12.2/Wed Feb 24 01:04:23 2016//Trc-1-5-7 22 | /transformation.py/1.45.12.1/Thu Feb 11 23:15:05 2016//Trc-1-5-7 23 | /transformationtest.py/1.3.12.1/Thu Feb 11 23:15:05 2016//Trc-1-5-7 24 | /usr.py/1.3.12.1/Thu Feb 11 23:15:05 2016//Trc-1-5-7 25 | D 26 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/CVS/Entries.Log: -------------------------------------------------------------------------------- 1 | A D/Tests//// 2 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/CVS/Repository: -------------------------------------------------------------------------------- 1 | python/packages/share1.5/mglutil/math 2 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/CVS/Root: -------------------------------------------------------------------------------- 1 | :pserver:anonymous@orca.scripps.edu:/mnt/raid/services/cvs 2 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/CVS/Tag: -------------------------------------------------------------------------------- 1 | Trc-1-5-7 2 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/__init__.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import types 3 | 4 | def crossProduct (A, B, normal=True): 5 | """ Return cross product of two vectors A and B 6 | normal: return normalized vector 7 | """ 8 | res=[ A[1]*B[2] - A[2]*B[1], 9 | A[2]*B[0] - A[0]*B[2], 10 | A[0]*B[1] - A[1]*B[0] ] 11 | if normal: 12 | return norm(res) 13 | else: 14 | return res 15 | 16 | def norm (A): 17 | """ Return normalized vector A. 18 | """ 19 | if type(A) == list: 20 | A=numpy.array(A,'f') 21 | res= A/numpy.sqrt(numpy.dot(A,A)) 22 | return res.tolist() 23 | elif type(A)==numpy.ndarray: 24 | return A/numpy.sqrt(numpy.dot(A,A)) 25 | else: 26 | print("Need a list or numpy array") 27 | return None 28 | 29 | def getCenter(coords): 30 | """ get center of all the coords """ 31 | coords=numpy.array(coords, 'f') 32 | return (numpy.sum(coords, 0)/len(coords)).tolist() 33 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/gridDescriptor.py: -------------------------------------------------------------------------------- 1 | import string, types, numpy 2 | 3 | 4 | class ConstrainedParameterSet: 5 | 6 | def __init__(self): 7 | #conDict records constraints between parameters 8 | #key is parm1Name, name of parameter1 , 9 | #value is list of triples: (parm2Name, func, args) 10 | #changes in parm1 cause parm2 to be updated by func 11 | #eg: to enforce 12 | #self.center = 2*self.offset 13 | #so that changes in self.offset force changes in self.center 14 | #self.conDict['offset'] = [('center', numpy.multiply, ('offset, 2.0'))] 15 | #to enforce the reciprocal constraint 16 | #so that changes in self.center force changes in self.offset 17 | #self.conDict['center'] = [('offset', numpy.multiply, ('center,0.5'))] 18 | #suitable functions are numpy.divide and numpy.multiply 19 | #DO SOMETHING SO THIS DOESN'T GET into an endless loop 20 | # 21 | self.conDict = {} 22 | #rangeDict provides methods of checking validity 23 | #of a given value for key 24 | #possible types methods include: 25 | #list of discrete values, tuple defining valid range, a type 26 | #or a function which returns 1 if value is valid or 0 if not 27 | self.rangeDict = {} 28 | # values can be integers, floats, strings....??? 29 | self.typesList = [type(1), type(1.0), type('a')] 30 | 31 | 32 | def tie(self, parm1Name, parm2Name, func, args): 33 | #eg: 34 | # changes in self.center force changes in self.offset 35 | # self.tie('center','offset',numpy.multiply,'center,2.0') 36 | if parm1Name not in self.conDict: 37 | self.conDict[parm1Name] = [] 38 | self.conDict[parm1Name].append((parm2Name, func, args)) 39 | #is this at all clear? 40 | #cD = self.conDict 41 | #cD[parm1Name] = cD.get(parm1Name, []).append((parm2Name, func, args)) 42 | 43 | 44 | def updateConstraints(self, parmName): 45 | #called when parm changes to update other linked parms 46 | conList = self.conDict.get(parmName, None) 47 | if not conList: 48 | # do nothing + return 49 | print('no constraints on ', parmName) 50 | return 51 | #conList has tuples (func, args) 52 | #eg: sample value in conList 53 | # (parm2Name, numpy.multiply, (parmName, 0.5)) 54 | for parm2Name, func, args in conList: 55 | #FIX THIS: 56 | #to update self.parm2Name: 57 | # need to get (self.center, 0.5) from args='center, 0.5' 58 | setattr(self,parm2Name, func(*eval('self.'+args))) 59 | 60 | 61 | def untie(self, parm1Name, parm2Name, func, args): 62 | #eg: 63 | #g.untie('center','offset',numpy.multiply,'center,2.0') 64 | conList = self.conDict.get(parm1Name, None) 65 | if not conList: 66 | print('no constraints on ', parm1Name) 67 | return "ERROR" 68 | if (parm2Name, func, args) not in conList: 69 | print('(%s,%s,%s) not in %s constraints'%(parm2Name, func, args, parm1Name)) 70 | return "ERROR" 71 | self.conDict[parm1Name].remove((parm2Name, func, args)) 72 | 73 | 74 | def setRange(self, parm, range): 75 | #range can be list, interval tuple, type or validation func 76 | #FIX THIS: do some range validation 77 | self.rangeDict[parm] = range 78 | 79 | 80 | def validateValue(self, parm, value): 81 | rangeD = self.rangeDict 82 | if parm not in rangeD: 83 | #nothing specified for this parm 84 | return value 85 | range = rangeD[parm] 86 | if type(range)==list: 87 | if value in range: 88 | return value 89 | else: 90 | return "ERROR: value not in range list" 91 | elif type(range)==tuple: 92 | if value>=range[0]and value<=range[1]: 93 | return value 94 | else: 95 | return "ERROR: value not in range interval" 96 | elif range in self.typesList: 97 | if type(value)==range: 98 | return value 99 | else: 100 | return "ERROR: value not specified type" 101 | else: 102 | #only thing left is validation function 103 | ok = list(range(*value)) 104 | if ok: 105 | return value 106 | else: 107 | return "ERROR: value failed validation func" 108 | 109 | 110 | def update(self, parm, value): 111 | check = self.validateValue(parm, value) 112 | if check!=value: 113 | print('failed validation:\n', check) 114 | return "ERROR" 115 | self.updateConstraints(parm) 116 | 117 | 118 | def fix(self, parmName): 119 | #???????????????????????????? 120 | #this method makes self.parmName constant 121 | #by removing any constraints which force it to change 122 | for k, v in list(self.conDict.items()): 123 | for triple in v: 124 | if triple[0]==parmName: 125 | self.conDict[k].remove(triple) 126 | 127 | 128 | 129 | 130 | class GeneralRegularGridDescriptor(ConstrainedParameterSet): 131 | 132 | keywords = ['center', 133 | 'offset', 134 | 'length', 135 | 'nbGridPoints', 136 | 'gridSpacing' 137 | ] 138 | 139 | def __init__(self, **kw): 140 | 141 | ConstrainedParameterSet.__init__(self) 142 | 143 | for k in self.keywords: 144 | setattr(self, k, kw.get(k, numpy.array((0.,0.,0.)))) 145 | 146 | consDict = kw.get('consDict', None) 147 | if consDict: 148 | for k, v in list(consDict.items()): 149 | self.tie(k, v[0], v[1], v[2]) 150 | 151 | rangeDict = kw.get('rangeDict', None) 152 | if rangeDict: 153 | for k, v in list(rangeDict.items()): 154 | self.setRange(k, v) 155 | 156 | fixed = kw.get('fixed', None) 157 | if fixed: 158 | #fixed should be a list of parameters to fix 159 | #same problem of type(parm)...a string??? 160 | for p in fixed: 161 | self.fix(p) 162 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/kmeansClustering.py: -------------------------------------------------------------------------------- 1 | import random 2 | import numpy 3 | from math import sqrt 4 | # -- The Point class represents points in n-dimensional space 5 | 6 | class Point: 7 | # Instance variables 8 | # self.coords is a list of coordinates for this Point 9 | # self.n is the number of dimensions this Point lives in (ie, its space) 10 | # self.reference is an object bound to this Point 11 | # Initialize new Points 12 | 13 | def __init__(self, coords, reference=None): 14 | self.coords = coords 15 | self.n = len(coords) 16 | self.reference = reference 17 | # Return a string representation of this Point 18 | 19 | def __repr__(self): 20 | return str(self.coords) 21 | # -- The Cluster class represents clusters of points in n-dimensional space 22 | 23 | 24 | class Cluster: 25 | # Instance variables 26 | # self.points is a list of Points associated with this Cluster 27 | # self.n is the number of dimensions this Cluster's Points live in 28 | # self.centroid is the sample mean Point of this Cluster 29 | 30 | def __init__(self, points): 31 | # We forbid empty Clusters (they don't make mathematical sense!) 32 | if len(points) == 0: raise Exception("ILLEGAL: EMPTY CLUSTER") 33 | self.points = points 34 | self.n = points[0].n 35 | # We also forbid Clusters containing Points in different spaces 36 | # Ie, no Clusters with 2D Points and 3D Points 37 | for p in points: 38 | if p.n != self.n: raise Exception("ILLEGAL: MULTISPACE CLUSTER") 39 | # Figure out what the centroid of this Cluster should be 40 | self.centroid = self.calculateCentroid() 41 | # Return a string representation of this Cluster 42 | 43 | def __repr__(self): 44 | return str(self.points) 45 | # Update function for the K-means algorithm 46 | # Assigns a new list of Points to this Cluster, returns centroid difference 47 | 48 | def update(self, points): 49 | old_centroid = self.centroid 50 | self.points = points 51 | self.centroid = self.calculateCentroid() 52 | x1,y1,z1 = old_centroid.coords 53 | x2,y2,z2 = self.centroid.coords 54 | return sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2) ) 55 | 56 | # Calculates the centroid Point - the centroid is the sample mean Point 57 | # (in plain English, the average of all the Points in the Cluster) 58 | def calculateCentroid(self): 59 | centroid_coords = [] 60 | # For each coordinate: 61 | for i in range(self.n): 62 | # Take the average across all Points 63 | centroid_coords.append(0.0) 64 | for p in self.points: 65 | centroid_coords[i] = centroid_coords[i]+p.coords[i] 66 | centroid_coords[i] = centroid_coords[i]/len(self.points) 67 | # Return a Point object using the average coordinates 68 | return Point(centroid_coords) 69 | 70 | def radiusOfGyration(self): 71 | ptCoords = [x.coords for x in self.points] 72 | delta = numpy.array(ptCoords)-self.centroid.coords 73 | rg = sqrt( sum( numpy.sum( delta*delta, 1))/float(len(ptCoords)) ) 74 | return rg 75 | 76 | def encapsualtingRadius(self): 77 | ptCoords = [x.coords for x in self.points] 78 | delta = numpy.array(ptCoords)-self.centroid.coords 79 | rM = sqrt( max( numpy.sum( delta*delta, 1)) ) 80 | return rM 81 | 82 | 83 | # -- Return Clusters of Points formed by K-means clustering 84 | def kmeans(points, k, cutoff, initial=None): 85 | # Randomly sample k Points from the points list, build Clusters around them 86 | if initial is None: 87 | # Randomly sample k Points from the points list, build Clusters around them 88 | initial = random.sample(points, k) 89 | else: 90 | assert len(initial)==k 91 | 92 | clusters = [] 93 | for p in initial: clusters.append(Cluster([p])) 94 | # Enter the program loop 95 | while True: 96 | # Make a list for each Cluster 97 | lists = [] 98 | for c in clusters: lists.append([]) 99 | # For each Point: 100 | for p in points: 101 | # Figure out which Cluster's centroid is the nearest 102 | x1,y1,z1 = p.coords 103 | x2,y2,z2 = clusters[0].centroid.coords 104 | smallest_distance = sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + 105 | (z1-z2)*(z1-z2) ) 106 | index = 0 107 | for i in range(len(clusters[1:])): 108 | x2,y2,z2 = clusters[i+1].centroid.coords 109 | distance = sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + 110 | (z1-z2)*(z1-z2) ) 111 | if distance < smallest_distance: 112 | smallest_distance = distance 113 | index = i+1 114 | # Add this Point to that Cluster's corresponding list 115 | lists[index].append(p) 116 | # Update each Cluster with the corresponding list 117 | # Record the biggest centroid shift for any Cluster 118 | biggest_shift = 0.0 119 | for i in range(len(clusters)): 120 | if len(lists[i]): 121 | shift = clusters[i].update(lists[i]) 122 | biggest_shift = max(biggest_shift, shift) 123 | # If the biggest centroid shift is less than the cutoff, stop 124 | if biggest_shift < cutoff: break 125 | # Return the list of Clusters 126 | return clusters 127 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/munkresLICENSE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MatthijsHak/MetalDock/73a52ccf1bd1a8d199f80405ee9da70135c7cda6/src/external/AutoDockTools/mglutil/math/munkresLICENSE -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/ncoords.py: -------------------------------------------------------------------------------- 1 | # 2 | # Last modified on Tue Sep 4 16:32:29 PDT 2001 by lindy 3 | # 4 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/mglutil/math/ncoords.py,v 1.2.12.1 2016/02/11 19:04:10 annao Exp $ 5 | # 6 | 7 | """ncoords.py - Numeric coordinates 8 | 9 | This class is intented to be the base class of a number 10 | of classes which transform and generally operate on lists 11 | of homogeneous coordinates. 12 | """ 13 | 14 | import numpy 15 | 16 | class Ncoords: 17 | def __init__(self, refCoords, tolist=1): 18 | """refCoords is an nx3 list of n points 19 | 20 | resultCoords is set up and maintained as homogeneous coords 21 | if tolist then return the result coords as a python list 22 | """ 23 | try: 24 | self.refCoords = numpy.array(numpy.concatenate( 25 | (refCoords, numpy.ones( (len(refCoords), 1), 'f')), 1)) 26 | except TypeError: 27 | raise ValueError("invalid input array") 28 | 29 | self.resultCoords = self.refCoords 30 | self.tolist = tolist 31 | 32 | 33 | def reset(self): 34 | self.resultCoords = self.refCoords 35 | 36 | 37 | def getResultCoords(self): 38 | """Return the list of result coordinates 39 | 40 | if tolist is set, return an nx3 Python ListType. 41 | if tolist is not set, return an nx4 numpy array. 42 | """ 43 | if self.tolist: 44 | return self.resultCoords[:,:3].tolist() 45 | else: 46 | return self.resultCoords 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/ncoordstest.py: -------------------------------------------------------------------------------- 1 | # 2 | # Last modified on Tue Sep 4 17:02:59 PDT 2001 by lindy 3 | # 4 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/mglutil/math/ncoordstest.py,v 1.2.12.1 2016/02/11 19:04:10 annao Exp $ 5 | # 6 | 7 | """Unit test for ncoords.py 8 | 9 | Requirements for ncoords.py: 10 | A. __init__: 11 | 1. make Numeric, homogenious coordinates out of refCoords 12 | 2. raise ValueError if refCoords is bad 13 | B. reset(): 14 | 3. nx3 slice of resultCoords must be equal to refCoords 15 | C. getResultCoords: 16 | 4. return nx3 (not nx4) coordinates 17 | 5. return as numpy.array or ListType accorinding to self.tolist 18 | """ 19 | 20 | from mglutil.math.ncoords import Ncoords 21 | import unittest, math 22 | import numpy 23 | import numpy.random as RandomArray 24 | 25 | 26 | 27 | 28 | class NcoordsTest(unittest.TestCase): 29 | def setUp(self): 30 | """Called for every test.""" 31 | 32 | npts = 500 33 | dim = 3 34 | self.max = 9999999. 35 | self.min = -self.max 36 | self.random_points = RandomArray.uniform(self.min, 37 | self.max, (npts,dim)).tolist() 38 | 39 | 40 | def tearDown(self): 41 | pass 42 | 43 | 44 | 45 | class InputOutputValues(NcoordsTest): 46 | 47 | 48 | def test_constructor_shape(self): 49 | """__init__ -- make refCoords and resultCoords homogeneous""" 50 | n = len(self.random_points) 51 | ncoords = Ncoords( self.random_points) ### tested call ### 52 | # confirm shape to be nx4 53 | self.assertEqual( (n, 4), numpy.shape(ncoords.resultCoords)) 54 | self.assertEqual( (n, 4), numpy.shape(ncoords.refCoords)) 55 | # cofirm that the last column is all ones 56 | self.assertEqual(numpy.ones(n).tolist(), 57 | ncoords.resultCoords[:,3].tolist()) 58 | self.assertEqual(numpy.ones(n).tolist(), 59 | ncoords.refCoords[:,3].tolist()) 60 | 61 | 62 | def test_input_error(self): 63 | """__init__ -- ValueError on bad input""" 64 | self.assertRaises(ValueError, Ncoords, list(range(10))) 65 | self.assertRaises(ValueError, Ncoords, [(1,1,1),(1,1)] ) 66 | 67 | 68 | def test_reset_values(self): 69 | """reset -- points equal input values after reset""" 70 | nc = Ncoords( self.random_points, tolist=1) 71 | nc.reset() ### tested call ### 72 | result = nc.getResultCoords() 73 | # compare input and output point lists 74 | self.assertEqual( self.random_points, result) 75 | 76 | 77 | def test_getResultCoords_shape(self): 78 | """getResultCoords -- if tolist: return nx3 ListType""" 79 | n = len(self.random_points) 80 | nc = Ncoords(self.random_points, tolist=0) 81 | nc.tolist=1 82 | result = nc.getResultCoords() ### tested call ### 83 | # confirm shape 84 | self.assertEqual((n, 3), numpy.shape(result)) 85 | # confirm type 86 | self.assertEqual(type([]), type(result)) 87 | 88 | 89 | def test_getResultCoords_type(self): 90 | """getResultCoords -- if not tolist: return nx4 numpy.array""" 91 | n = len(self.random_points) 92 | nc = Ncoords(self.random_points, tolist=1) 93 | nc.tolist=0 94 | result = nc.getResultCoords() ### tested call ### 95 | # confirm shape 96 | self.assertEqual((n, 4), numpy.shape(result)) 97 | # confirm type 98 | self.assertEqual(type(numpy.array([])), type(result)) 99 | 100 | 101 | 102 | if __name__ == '__main__': 103 | unittest.main() 104 | 105 | # for example: 106 | # py mglutil/math/ncoordstest.py -v 107 | # or, to redirect output to a file: 108 | # py ncoordstest.py -v > & ! /tmp/nct.out 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/rmsdtest.py: -------------------------------------------------------------------------------- 1 | # 2 | # Last modified on Thu Jan 31 10:27:11 PST 2002 by lindy 3 | # 4 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/mglutil/math/rmsdtest.py,v 1.4.12.1 2016/02/11 23:15:05 annao Exp $ 5 | # 6 | """Unit test for rmsd.py 7 | 8 | Requirements for rmsd: 9 | A. RMSDCalculator.__init__ 10 | 0. should .. 11 | B. RMSDCalculator.setRefCoords 12 | 0. should .. 13 | C. RMSDCalculator.computeRMSD 14 | 1. should return known result with known input 15 | 2. raise ValueError for input of unlike dimensions 16 | 3. for two random sets of points, rmsd(x,y) == rmsd(y,x) 17 | 4. raise ValueError if the reference coords have not been set 18 | D. 19 | 20 | """ 21 | 22 | from mglutil.math import rmsd 23 | import unittest, math 24 | import numpy 25 | from numpy import random as RandomArray 26 | 27 | class ComputedValues(unittest.TestCase): 28 | decimals = 4 # decimal places to round to for float comparison 29 | point_list_0 = numpy.zeros((5,3)) 30 | point_list_1 = numpy.ones( (5,3)) 31 | 32 | knowValues = ( (point_list_0, point_list_0, 0.0), 33 | (point_list_1, point_list_1, 0.0), 34 | (point_list_0, point_list_1, math.sqrt(3.0)), 35 | (point_list_1, point_list_0, math.sqrt(3.0))) 36 | 37 | def test_computeRMSD_KnowValues(self): 38 | """1. should return known result with known input""" 39 | for ref, input, known in self.knowValues: 40 | self.assertEqual(known, 41 | rmsd.RMSDCalculator(ref).computeRMSD(input)) 42 | 43 | 44 | def test_computeRMSD_RandomOffset(self): 45 | """5. offset point by random value returns offset*sqrt(3)""" 46 | min = -10000. 47 | max = 10000. 48 | num_points = 20 49 | dimension = 3 50 | point_list_1 = RandomArray.uniform(min, max, (num_points, dimension)) 51 | delta = point_list_1[0][0] 52 | point_list_2 = point_list_1 + delta 53 | answer = rmsd.RMSDCalculator(point_list_1).computeRMSD(point_list_2) 54 | self.assertEqual( 55 | round(answer, self.decimals), 56 | round(abs(delta)*math.sqrt(3.0), self.decimals)) 57 | 58 | 59 | def test_computeRMSD_Random(self): 60 | """3. for two random sets of points, rmsd(x,y) == rmsd(y,x)""" 61 | min = -10000. 62 | max = 10000. 63 | num_points = 20 64 | dimension = 3 65 | point_list_1 = RandomArray.uniform(min, max, (num_points, dimension)) 66 | point_list_2 = RandomArray.uniform(min, max, (num_points, dimension)) 67 | self.assertEqual( 68 | rmsd.RMSDCalculator(point_list_1).computeRMSD(point_list_2), 69 | rmsd.RMSDCalculator(point_list_2).computeRMSD(point_list_1)) 70 | 71 | 72 | class InputValues(unittest.TestCase): 73 | point_list_0 = numpy.zeros((3,3)) 74 | point_list_1 = numpy.ones( (4,3)) # different lengths 75 | 76 | def test_computeRMSD_dimensions(self): 77 | """2. raise ValueError for input of unlike dimensions""" 78 | ruler = rmsd.RMSDCalculator(self.point_list_0) 79 | self.assertRaises(ValueError, ruler.computeRMSD, self.point_list_1) 80 | 81 | def test_computeRMSD_noRefCoords(self): 82 | """4. raise ValueError if the reference coords have not been set""" 83 | ruler = rmsd.RMSDCalculator() 84 | self.assertRaises(ValueError, ruler.computeRMSD, self.point_list_1) 85 | 86 | if __name__ == "__main__": 87 | unittest.main() 88 | 89 | # for example: py mglutil/math/rmsdtest.py -v 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/statetocoords.py: -------------------------------------------------------------------------------- 1 | # 2 | # Last modified on Tue Apr 23 09:20:22 PDT 2002 by lindy 3 | # 4 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/mglutil/math/statetocoords.py,v 1.11.10.1 2016/02/11 23:15:05 annao Exp $ 5 | # 6 | 7 | """statetocoords.py - state to coordinates 8 | 9 | The StateToCoords class inherits from Kinematics and Ncoords. 10 | The StateToCoords class handles transformations that apply to 11 | the rootNode of the torTree, changing the coordinates in world 12 | space. The Kinematics class handles those transformations that 13 | apply to the internal nodes to the torTree (ie. torsions) changing 14 | the coordinates in the molecules local coordinate system. 15 | """ 16 | import numpy 17 | import math 18 | from mglutil.math.transformation import Transformation 19 | from mglutil.math.kinematics import Kinematics 20 | 21 | 22 | class StateToCoords(Kinematics): 23 | def __init__(self, mol, origin, confIndex): 24 | Kinematics.__init__(self, mol.allAtoms.coords, mol.torTree, tolist=1) 25 | # this stoc object will leave always deposite it's coords 26 | # in the given confIndex slot. 27 | self.confIndex = confIndex 28 | 29 | mol.allAtoms.setConformation(confIndex) 30 | 31 | def __prepareNode(node, allAtoms, o): 32 | """Supply each node with atomSet, coords, and atomRange, 33 | Pre-compute and save the torsionUnitVector, 34 | Transform the coords to their local space by subtracting 35 | the origin 36 | """ 37 | atomSet = [] 38 | coords = [] 39 | for i in node.atomList: 40 | atom = allAtoms[i] 41 | atomSet.append(atom) 42 | # start with the original coordinates 43 | c = atom.coords 44 | # subract the origin 45 | coords.append((c[0]-o[0], c[1]-o[1], c[2]-o[2], 1.0)) 46 | node.atomSet = atomSet 47 | node.coords = coords 48 | node.atomRange = list(range(len(atomSet))) 49 | if node.bond[0] != None: # skip the root node 50 | node.a = allAtoms[node.bond[0]] 51 | node.b = allAtoms[node.bond[1]] 52 | 53 | # add atomSets to each node 54 | root = mol.torTree.rootNode 55 | root.pre_traverse(__prepareNode, root, mol.allAtoms, origin) 56 | 57 | 58 | def applyState(self, state): 59 | """ 60 | """ 61 | q = state.quaternion 62 | t = numpy.array(state.translation) 63 | o = numpy.array(state.origin) 64 | 65 | # construct rootNode transformation matrix 66 | #mtx = Transformation(t+o, q).getMatrix(transpose=1) 67 | # Corrected by AG 08/28/2008 68 | mtx = Transformation(t, q).getMatrix().transpose() 69 | 70 | # apply the torsions 71 | self.applyAngList(state.torsions, mtx) 72 | 73 | 74 | def applyStateOld(self, state): 75 | """ 76 | """ 77 | q = state.quaternion 78 | t = numpy.array(state.translation) 79 | o = numpy.array(state.origin) 80 | 81 | # center the coordinates 82 | ## self.resultCoords = (self.resultCoords - 83 | ## numpy.array([o[0], o[1], o[2], 0.0])) 84 | 85 | # center the coordinates (node-by-node) 86 | def __center(node, o): node.coords = node.coords - o 87 | root = self.torTree.rootNode 88 | root.pre_traverse(__center, root, numpy.array([o[0], o[1], o[2], 0.0])) 89 | 90 | # construct rootNode transformation matrix 91 | mtx = Transformation(t+o, q).getMatrix(transpose=1) 92 | 93 | # apply the torsions 94 | coords = self.applyAngList(state.torsions, mtx) 95 | 96 | # must "reset" each nodes coords 97 | def __uncenter(node, o): node.coords = node.coords + o 98 | root.pre_traverse(__uncenter, root, numpy.array([o[0], o[1], o[2], 0.0])) 99 | 100 | return coords 101 | 102 | 103 | def applyOrientation(self, q=(0.,0.,0.,0.), t=(0.,0.,0.), o=(0.,0.,0.)): 104 | """origin specifies where the local origin is in world coordinates 105 | (i.e., where is this object's origin in the world) 106 | """ 107 | # center the coordinates 108 | self.resultCoords = (self.resultCoords - 109 | numpy.array([o[0], o[1], o[2], 0.0])) 110 | sum = numpy.array(t) + numpy.array(o) 111 | self.resultCoords = Transformation(sum, q).apply(self.resultCoords) 112 | return self.getResultCoords() 113 | 114 | 115 | def applyQuaternion(self, q, o=(0.,0.,0.)): 116 | """Apply the given quaterion. 117 | """ 118 | # center the coordinates 119 | self.resultCoords = (self.resultCoords - 120 | numpy.array([o[0], o[1], o[2], 0.0])) 121 | self.resultCoords = Transformation(o, q).apply(self.resultCoords) 122 | return self.getResultCoords() 123 | 124 | 125 | def applyTranslation(self, t=(0., 0., 0.)): 126 | """Translate by (x, y, z) 127 | """ 128 | translation = numpy.array([t[0], t[1], t[2], 0.0]) 129 | self.resultCoords = self.resultCoords + translation 130 | return self.getResultCoords() 131 | 132 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/stats.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | 3 | def stats(values): 4 | """returns the mimn, max, mean and standard deviation of a list of values""" 5 | 6 | warnings.warn( 7 | "\n\nWARNING!! This function has been deprecated!!\n \ 8 | Use the stats in Volume/Grid3D.py\n",DeprecationWarning,2) 9 | 10 | npts = len(values) 11 | if npts: 12 | from math import sqrt 13 | sum = 0.0 14 | sumsq = 0.0 15 | mini = maxi = values[0] 16 | for v in values: 17 | sum += v 18 | sumsq += float(v)*float(v) 19 | if vmaxi: 22 | maxi = v 23 | mean = float(sum)/npts 24 | stdev = sqrt(( sumsq - (sum*sum/float(npts)))/(npts-1)) 25 | return mini, maxi, mean, stdev 26 | 27 | else: 28 | return (0., 0., 1., 1.) 29 | 30 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/torsion.py: -------------------------------------------------------------------------------- 1 | #taken from Pmv/measureCommands.py 2 | import numpy 3 | 4 | def torsion( x1, x2, x3, x4): 5 | """ 6 | Compute the torsion angle between x1, x2, x3, x4. 7 | All coordinates are cartesian; result is in degrees. 8 | Raises a ValueError if angle is not defined. 9 | """ 10 | from math import sqrt, acos 11 | 12 | tang=0.0 13 | x1 = numpy.array(x1, 'f') 14 | x2 = numpy.array(x2, 'f') 15 | x3 = numpy.array(x3, 'f') 16 | x4 = numpy.array(x4, 'f') 17 | 18 | assert x1.shape == (3, ) 19 | assert x2.shape == (3, ) 20 | assert x3.shape == (3, ) 21 | assert x4.shape == (3, ) 22 | 23 | a = x1-x2 24 | b = x3-x2 25 | c = vvmult(a, b) 26 | 27 | a = x2-x3 28 | b = x4-x3 29 | d = vvmult(a, b) 30 | 31 | dd=sqrt(numpy.sum(c*c)) 32 | de=sqrt(numpy.sum(d*d)) 33 | 34 | if dd<0.001 or de<0.001: 35 | raise ValueError ( 'Torsion angle undefined, degenerate points') 36 | 37 | vv = numpy.dot(c, d) / (dd*de); 38 | if vv<1.0: tang=vv 39 | else: tang= 1.0 40 | if tang<-1.0: tang=-1.0 41 | tang = acos(tang) 42 | tang = tang*57.296 43 | 44 | b = vvmult(c, d) 45 | if numpy.dot(a, b) > 0.0: tang = -tang 46 | return tang 47 | 48 | def vvmult( a, b): 49 | """ 50 | Compute a vector product for 3D vectors 51 | """ 52 | res = numpy.zeros(3, 'f') 53 | res[0] = a[1]*b[2] - a[2]*b[1] 54 | res[1] = a[2]*b[0] - a[0]*b[2] 55 | res[2] = a[0]*b[1] - a[1]*b[0] 56 | return res 57 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/math/transformationtest.py: -------------------------------------------------------------------------------- 1 | # 2 | # Last modified on Wed Aug 22 14:22:48 PDT 2001 by lindy 3 | # 4 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/mglutil/math/transformationtest.py,v 1.3.12.1 2016/02/11 23:15:05 annao Exp $ 5 | # 6 | 7 | """Unit test for transformation.py 8 | 9 | Transformation.py defines three classes: 10 | Quaternion 11 | UnitQuaternion(Quaternion) 12 | Transformation(UnitQuaternion) 13 | 14 | """ 15 | 16 | from mglutil.math.transformation import UnitQuaternion, Quaternion 17 | from mglutil.math.transformation import Transformation 18 | import unittest 19 | from numpy import random as RA 20 | import math 21 | 22 | # 23 | # Unit tests for the Quaternion class 24 | # 25 | 26 | class QuaternionTest(unittest.TestCase): 27 | def setUp(self): 28 | """The Quaternion class is tested through the UnitQuaternion class""" 29 | pass 30 | 31 | 32 | 33 | class UnitQuaternionTest(unittest.TestCase): 34 | def setUp(self): 35 | self.max = 999999999. 36 | self.min = -self.max 37 | 38 | 39 | 40 | class UnitQuaternionKnownValues(UnitQuaternionTest): 41 | ## theta = 360.0*RA.random() 42 | ## knownValues = ( 43 | ## # identity 44 | ## ((0., 0., 0., 0.), ( (1.0, 0.0, 0.0, 0.0), 45 | ## (0.0, 1.0, 0.0, 0.0), 46 | ## (0.0, 0.0, 1.0, 0.0), 47 | ## (0.0, 0.0, 0.0, 1.0))), 48 | ## # rotation about x 49 | ## ((0., 0., 0., 0.), ( (1.0, 0.0, 0.0, 0.0), 50 | ## (0.0, 1.0, 0.0, 0.0), 51 | ## (0.0, 0.0, 1.0, 0.0), 52 | ## (0.0, 0.0, 0.0, 1.0))), 53 | ## # rotation about y 54 | ## ((0., 0., 0., 0.), ( (1.0, 0.0, 0.0, 0.0), 55 | ## (0.0, 1.0, 0.0, 0.0), 56 | ## (0.0, 0.0, 1.0, 0.0), 57 | ## (0.0, 0.0, 0.0, 1.0))), 58 | ## # rotation about z 59 | ## ((0., 0., 0., 0.), ( (1.0, 0.0, 0.0, 0.0), 60 | ## (0.0, 1.0, 0.0, 0.0), 61 | ## (0.0, 0.0, 1.0, 0.0), 62 | ## (0.0, 0.0, 0.0, 1.0))), 63 | ## ((0., 0., 0., 0.), ( (1.0, 0.0, 0.0, 0.0), 64 | ## (0.0, 1.0, 0.0, 0.0), 65 | ## (0.0, 0.0, 1.0, 0.0), 66 | ## (0.0, 0.0, 0.0, 1.0))), 67 | ## ((0., 0., 0., 0.), ( (1.0, 0.0, 0.0, 0.0), 68 | ## (0.0, 1.0, 0.0, 0.0), 69 | ## (0.0, 0.0, 1.0, 0.0), 70 | ## (0.0, 0.0, 0.0, 1.0))), 71 | ## ((0., 0., 0., 0.), ( (1.0, 0.0, 0.0, 0.0), 72 | ## (0.0, 1.0, 0.0, 0.0), 73 | ## (0.0, 0.0, 1.0, 0.0), 74 | ## (0.0, 0.0, 0.0, 1.0))), 75 | ## ((0., 0., 0., 0.), ( (1.0, 0.0, 0.0, 0.0), 76 | ## (0.0, 1.0, 0.0, 0.0), 77 | ## (0.0, 0.0, 1.0, 0.0), 78 | ## (0.0, 0.0, 0.0, 1.0))), 79 | ## ((0., 0., 0., 0.), ( (1.0, 0.0, 0.0, 0.0), 80 | ## (0.0, 1.0, 0.0, 0.0), 81 | ## (0.0, 0.0, 1.0, 0.0), 82 | ## (0.0, 0.0, 0.0, 1.0)))) 83 | 84 | def tearDown(self): 85 | pass 86 | 87 | 88 | def testKnown00(self): 89 | """""" 90 | pass 91 | 92 | 93 | 94 | class UnitQuaternionProperties(UnitQuaternionTest): 95 | 96 | def testProperties00(self): 97 | """The product of the conjugate is the conjucate of the product""" 98 | q1 = Quaternion(tuple(RA.uniform(self.min, 99 | self.max, (1, 4)).tolist()[0])) 100 | q2 = Quaternion(tuple(RA.uniform(self.min, 101 | self.max, (1, 4)).tolist()[0])) 102 | ## pc = q1.conjugate()*q2.conjugate() 103 | ## qp = q1*q2 104 | ## cp = qp.conjugate() 105 | ## self.assertEqual( pc, cp) 106 | # the commented code fails with the same error as this line... 107 | self.assertEqual( q1.conjugate()*q2.conjugate(), (q2*q1).conjugate()) 108 | 109 | 110 | def testProperties01(self): 111 | """The magnitudue of the product is the product of the magnitudes""" 112 | q1 = Quaternion(tuple(RA.uniform(self.min, 113 | self.max, (1, 4)).tolist()[0])) 114 | q2 = Quaternion(tuple(RA.uniform(self.min, 115 | self.max, (1, 4)).tolist()[0])) 116 | self.assertEqual((q1*q2).magnitude(), q1.magnitude()*q2.magnitude()) 117 | 118 | 119 | def testProperties02(self): 120 | """The conjugate of a unit quaternion is it's inverse""" 121 | q1 = Quaternion(tuple(RA.uniform(self.min, 122 | self.max, (1, 4)).tolist()[0])) 123 | self.assertEqual( q1.conjugate(), q1.inverse()) 124 | 125 | 126 | 127 | 128 | class TransformationTest(unittest.TestCase): 129 | def setUp(self): 130 | pass 131 | 132 | 133 | def tearDown(self): 134 | pass 135 | 136 | def test(self): 137 | pass 138 | 139 | 140 | 141 | if __name__ == '__main__': 142 | unittest.main() 143 | 144 | # for example: py mglutil/math/transformationtest.py -v 145 | 146 | 147 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/CVS/Entries: -------------------------------------------------------------------------------- 1 | /__init__.py/1.1.1.1/Mon May 14 21:21:42 2001//Trc-1-5-7 2 | /callback.py/1.10.12.2/Thu Apr 6 23:02:57 2017//Trc-1-5-7 3 | /colorUtil.py/1.15.12.1/Thu Feb 11 23:15:05 2016//Trc-1-5-7 4 | /defaultPalettes.py/1.6/Mon Jun 13 21:40:34 2011//Trc-1-5-7 5 | /idleUtil.py/1.9/Tue Sep 23 18:07:18 2008//Trc-1-5-7 6 | /misc.py/1.19.4.1/Thu Feb 11 23:15:05 2016//Trc-1-5-7 7 | /packageFilePath.py/1.56/Mon Sep 24 23:26:51 2012//Trc-1-5-7 8 | /parser.py/1.5.12.1/Thu Feb 11 23:15:05 2016//Trc-1-5-7 9 | /qhullUtils.py/1.13/Mon Dec 1 21:12:37 2008//Trc-1-5-7 10 | /recentFiles.py/1.16/Tue Oct 5 17:25:40 2010//Trc-1-5-7 11 | /relpath.py/1.1/Tue Aug 28 18:51:43 2007//Trc-1-5-7 12 | /repeatPrinter.py/1.1/Wed Jul 8 19:15:36 2009//Trc-1-5-7 13 | /tree.py/1.3/Wed Oct 10 22:27:01 2001//Trc-1-5-7 14 | /uniq.py/1.3/Mon Jun 14 22:58:18 2004//Trc-1-5-7 15 | D 16 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/CVS/Entries.Log: -------------------------------------------------------------------------------- 1 | A D/Tests//// 2 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/CVS/Repository: -------------------------------------------------------------------------------- 1 | python/packages/share1.5/mglutil/util 2 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/CVS/Root: -------------------------------------------------------------------------------- 1 | :pserver:anonymous@orca.scripps.edu:/mnt/raid/services/cvs 2 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/CVS/Tag: -------------------------------------------------------------------------------- 1 | Trc-1-5-7 2 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MatthijsHak/MetalDock/73a52ccf1bd1a8d199f80405ee9da70135c7cda6/src/external/AutoDockTools/mglutil/util/__init__.py -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/callback.py: -------------------------------------------------------------------------------- 1 | # 2 | # Author Michel F. Sanner (may 2001) Copyright M. Sanner, TSRI 3 | # 4 | # $Id: callback.py,v 1.10.12.2 2017/04/06 23:02:57 annao Exp $ 5 | # 6 | # $Author: annao $ 7 | # 8 | import traceback 9 | import types 10 | 11 | class CallbackManager: 12 | """Class to manage a list of callback functions""" 13 | 14 | def __init__(self): 15 | self.callbacks = [] 16 | 17 | 18 | def FindFunctionByName(self, funcName): 19 | """find a function with a given name in a list of functions""" 20 | 21 | for f in self.callbacks: 22 | if f.__name__==funcName: return f 23 | return None 24 | 25 | 26 | def SetCallback(self, func): 27 | """Delete all and set a callback fuction""" 28 | 29 | assert func is None or callable(func) 30 | if func is None: 31 | self.callbacks = [] 32 | else: 33 | self.callbacks = [func, ] 34 | 35 | 36 | def AddCallback(self, func): 37 | """Add a callback fuction""" 38 | 39 | assert callable(func) 40 | self.callbacks.append(func) 41 | 42 | 43 | def CallCallbacks(self, *args, **kw): 44 | """call all callback fuctions""" 45 | 46 | results = [] 47 | for func in self.callbacks: 48 | try: 49 | results.append( func(*args, **kw) ) 50 | 51 | except: 52 | print('ERROR ************************************************') 53 | traceback.print_exc() 54 | return 'ERROR' 55 | 56 | return results 57 | 58 | 59 | def ListCallbacks(self): 60 | for func in self.callbacks: 61 | print(func.__name__,func) 62 | 63 | 64 | def RemoveCallback(self, func): 65 | """Delete a callback fuction""" 66 | if type(func)==bytes: 67 | func = self.FindFunctionByName(func) 68 | if func is None: return "function %s not found"%func 69 | if func in self.callbacks: 70 | self.callbacks.remove(func) 71 | else: 72 | return "function %s not found"%func.__name__ 73 | 74 | 75 | class CallbackFunction: 76 | """Class to allow to specify arguments to a callback function""" 77 | 78 | def __init__(self, function, *args, **kw): 79 | self.function = function 80 | if hasattr(function, '__name__'): 81 | self.__name__ = function.__name__ 82 | elif hasattr(function, 'name'): 83 | self.__name__ = function.name 84 | elif hasattr(function, '__class__') and hasattr(function.__class__, '__name__'): 85 | self.__name__ = f.__class__.__name__ 86 | else: 87 | self.__name__ = 'noname' 88 | self.args = args 89 | self.kw = kw 90 | 91 | def __call__(self, *args, **kw): 92 | args = self.args + args 93 | kw.update(self.kw) 94 | return self.function(*args, **kw) 95 | 96 | CallBackFunction = CallbackFunction 97 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/defaultPalettes.py: -------------------------------------------------------------------------------- 1 | # 2 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/mglutil/util/defaultPalettes.py,v 1.6 2011/06/13 21:40:34 sargis Exp $ 3 | # 4 | # $Id: defaultPalettes.py,v 1.6 2011/06/13 21:40:34 sargis Exp $ 5 | # 6 | """ This file contains the default ColorPalette.""" 7 | ChooseColor = {'red':(1.,0.,0.), 'green':(0.,1.,0.), 8 | 'blue':(0.,0.,1.), 'white':(1.,1.,1.), 9 | 'black':(0.,0.,0.), 'cyan':(0.,1.,1.), 10 | 'yellow':(1.,1.,0.), 'magenta':(1.,0.,1.) 11 | } 12 | ChooseColorSortedKeys = [ 'white', 'black', 'red', 'green', 'blue', 13 | 'cyan', 'yellow', 'magenta' ] 14 | #Rainbow= {0: (0.,0.,1.), 1: (0.,1.,0.), 2: (1.,0.,0.), 15 | # 3: (0.,1.,1.), 4: (1.,1.,0.), 5: (1.,0.,1.), 16 | # 6: (0.,.75,1.), 7: (0.,1.,.5), 8: (.6,1.,0.), 17 | # 9: (1.,.5,0.), 10: (1.,0.,.5), 11:(.5,0.,1.), 18 | # 12:(.5,0.,.2), 13: (0.,.5,.2), 14:(0.75,0,1), 19 | # 15:(1.,0.75,0),16:(1.,0.,0.75,),17:(0., 1., .75), 20 | # 18:(1.,0.,0.25,), 19: (0.,.5,1.)} 21 | # 22 | #RainbowSortedKey = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19] 23 | 24 | Rainbow = {'0': (0.,0.,1.), '1': (0.,1.,0.), '2': (1.,0.,0.), 25 | '3': (0.,1.,1.), '4': (1.,1.,0.), '5': (1.,0.,1.), 26 | '6': (0.,.75,1.), '7': (0.,1.,.5), '8': (.6,1.,0.), 27 | '9': (1.,.5,0.), '10': (1.,0.,.5), '11':(.5,0.,1.), 28 | '12':(.5,0.,.2), '13': (0.,.5,.2), '14':(0.75,0,1), 29 | '15':(1.,0.75,0),'16':(1.,0.,0.75,),'17':(0., 1., .75), 30 | '18':(1.,0.,0.25,), '19': (0.,.5,1.)} 31 | 32 | MolColors = {'0': (1.,0.5,1.), '1': (0., 0.509,0.), '2': (1.,0.5,0.5), 33 | '3': (0.25,0.75,1.), '4': (0.517,0.2549,0.2588), '5': (1.,0.,1.), 34 | '6': (0.,.75,1.), '7': (0.,1.,.5), '8': (.6,1.,0.), 35 | '9': (1.,.5,0.), '10': (1.,0.,.5), '11':(.5,0.,1.), 36 | '12':(.5,0.,.2), '13': (0.,.5,.2), '14':(0.75,0,1), 37 | '15':(1.,0.75,0),'16':(1.,0.,0.75,),'17':(0., 1., .75), 38 | '18':(1.,0.,0.25,), '19': (0.,.5,1.)} 39 | 40 | RainbowSortedKey = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19'] 41 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/idleUtil.py: -------------------------------------------------------------------------------- 1 | from idlelib import PyShell 2 | #from idlelib.PyShell import PyShell, PyShellFileList, use_subprocess 3 | from idlelib.EditorWindow import fixwordbreaks 4 | import tkinter, sys, os 5 | def getShell(thread, rootTk = None, subprocess = False, debug=False, 6 | enable_shell=False, enable_edit=True): 7 | """ 8 | This function creates and returns a shell PyShell instance 9 | required arguments: 10 | thread -- 11 | 12 | optional arguments: 13 | rootTk -- 14 | subprocess -- boolean flag when set to True a the pyshell 15 | runs a new interpreter in a sub process 16 | when set to False it the user has access to the main 17 | interpreter. (default = False) 18 | enable_shell -- boolean flag when set to True a python shell is 19 | created (by default True) 20 | enable_edit -- boolean flag when set to True a edit shell is created 21 | aware of the python syntax (by default False) 22 | debug -- boolean flag when set to True starts the debugger when 23 | the pyshell is created. (by default = False) 24 | """ 25 | cmd = None 26 | script = None 27 | startup = False 28 | 29 | # try: 30 | # sys.ps1 31 | # except AttributeError: 32 | # sys.ps1 = '>>> ' 33 | 34 | if hasattr(sys, 'ps1') is False: 35 | sys.ps1 = '>>> ' 36 | 37 | global mainThread 38 | 39 | PyShell.use_subprocess = subprocess 40 | mainThread = thread 41 | for i in range(len(sys.path)): 42 | sys.path[i] = os.path.abspath(sys.path[i]) 43 | 44 | pathx = [] 45 | for dir in pathx: 46 | dir = os.path.abspath(dir) 47 | if not dir in sys.path: 48 | sys.path.insert(0, dir) 49 | 50 | global flist, root 51 | if rootTk is None: root = tkinter.Tk() 52 | else: root = rootTk 53 | fixwordbreaks(root) 54 | 55 | flist = PyShell.PyShellFileList(root) 56 | if enable_edit: 57 | flist.new() 58 | if enable_shell : 59 | flist.open_shell() 60 | elif enable_shell: 61 | flist.pyshell = PyShell.PyShell() 62 | #flist.pyshell.begin() 63 | shell = flist.pyshell 64 | if debug: 65 | shell.open_debugger() 66 | return shell 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/misc.py: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # 3 | # Author: Michel F. SANNER 4 | # 5 | # Copyright: M. Sanner TSRI 2000 6 | # 7 | ############################################################################# 8 | 9 | # 10 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/mglutil/util/misc.py,v 1.19.4.1 2016/02/11 23:15:05 annao Exp $ 11 | # 12 | # $Id: misc.py,v 1.19.4.1 2016/02/11 23:15:05 annao Exp $ 13 | # 14 | 15 | import types 16 | import sys 17 | import numpy 18 | import os 19 | 20 | _proc_status = '/proc/%d/status' % os.getpid() 21 | 22 | _scale = {'kB': 1024.0, 'mB': 1024.0*1024.0, 23 | 'KB': 1024.0, 'MB': 1024.0*1024.0} 24 | 25 | def _VmB(VmKey): 26 | '''Private. 27 | ''' 28 | global _proc_status, _scale 29 | # get pseudo file /proc//status 30 | try: 31 | t = open(_proc_status) 32 | v = t.read() 33 | t.close() 34 | except: 35 | return 0.0 # non-Linux? 36 | # get VmKey line e.g. 'VmRSS: 9999 kB\n ...' 37 | i = v.index(VmKey) 38 | v = v[i:].split(None, 3) # whitespace 39 | if len(v) < 3: 40 | return 0.0 # invalid format? 41 | # convert Vm value to bytes 42 | return float(v[1]) * _scale[v[2]] 43 | 44 | 45 | def memory(since=0.0): 46 | '''Return memory usage in bytes. 47 | ''' 48 | return _VmB('VmSize:') - since 49 | 50 | 51 | def resident(since=0.0): 52 | '''Return resident memory usage in bytes. 53 | ''' 54 | return _VmB('VmRSS:') - since 55 | 56 | 57 | def stacksize(since=0.0): 58 | '''Return stack size in bytes. 59 | ''' 60 | return _VmB('VmStk:') - since 61 | 62 | 63 | def issequence(a): 64 | return type(a) is tuple or \ 65 | type(a) is list or \ 66 | isinstance(a, numpy.ndarray) 67 | 68 | def isnumericstring(a): 69 | try: 70 | float(a) 71 | return 1 72 | except: 73 | return 0 74 | 75 | def uniq(objectSequence): 76 | """Remove the duplicates from a list while keeping the original 77 | list order """ 78 | l = [] 79 | d = {} 80 | for o in objectSequence: 81 | if o not in d: 82 | d[o] = None 83 | l.append(o) 84 | return l 85 | 86 | 87 | def deepCopySeq(sequence): 88 | """ returns the deep copy of the given sequence """ 89 | from types import TupleType, ListType 90 | assert type(sequence) in (TupleType, ListType, type(numpy.array([1,2,3]))) 91 | if hasattr(sequence, 'copy'): 92 | dcSeq = sequence.copy() 93 | else: 94 | dcSeq = sequence[:] 95 | 96 | return dcSeq 97 | 98 | 99 | def ensureFontCase(font): 100 | return font 101 | # from Tkinter import TkVersion 102 | # lFont = font[0].upper() + font[1:].lower() 103 | # if TkVersion == '8.4' and sys.platform != "win32": 104 | # lFont = font.lower() 105 | # return lFont 106 | 107 | 108 | def isInstance(lObject): 109 | 110 | import types 111 | if sys.version.startswith('2.5'): #detect python25 112 | if type(lObject) == types.InstanceType: 113 | return True 114 | else: 115 | return False 116 | else: 117 | import inspect 118 | ltype = type(lObject) 119 | if ltype == types.InstanceType: 120 | return True 121 | elif inspect.isclass(lObject) is False \ 122 | and isinstance(lObject, ltype) is True: 123 | from abc import ABCMeta 124 | if ltype == type is True: 125 | return True 126 | elif type(ltype) == ABCMeta: 127 | return True 128 | else: 129 | return False 130 | else: 131 | return False 132 | 133 | 134 | def importMainOrIPythonMain(): 135 | try: 136 | from IPython import ipapi 137 | mainDict = ipapi.get().user_ns 138 | except: 139 | mainDict = __import__('__main__').__dict__ 140 | return mainDict 141 | 142 | 143 | def suppressMultipleQuotes(aString): 144 | lStringToSimplify = aString 145 | lSimplifiedString = lStringToSimplify 146 | while type(lStringToSimplify) == bytes: 147 | lSimplifiedString = lStringToSimplify 148 | try: 149 | lStringToSimplify = eval(lSimplifiedString) 150 | except: 151 | break 152 | return lSimplifiedString 153 | 154 | 155 | class IntVar: 156 | def __init__(self, val=0): 157 | self.set(val) 158 | 159 | def get(self): 160 | return self.val 161 | 162 | def set(self,val): 163 | self.val = int(val) 164 | 165 | 166 | class StringVar: 167 | def __init__(self, val=""): 168 | self.set(val) 169 | 170 | def get(self): 171 | return self.val 172 | 173 | def set(self,val): 174 | self.val = str(val) 175 | 176 | 177 | class BooleanVar: 178 | def __init__(self, val=False): 179 | self.set(val) 180 | 181 | def get(self): 182 | return self.val 183 | 184 | def set(self,val): 185 | self.val = (val==True) 186 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/parser.py: -------------------------------------------------------------------------------- 1 | # 2 | # Author Daniel Stoffler (Dec 2001) Copyright D. Stoffler, TSRI 3 | 4 | import numpy 5 | import string 6 | 7 | class VRML2IndexedFaceSetToCoords: 8 | """ VRML2 IndexedFaceSet -> coords & indices. 9 | Please note this is BY NO MEANS a VRML parser but rather a hack that 10 | allows to convert SIMPLE VRML2 indexedFaceSets into coords and indices 11 | which can be displayed using the IndexedPolygon node of the ViPEr 12 | environment """ 13 | 14 | def init(self, data=None): 15 | self.data = data 16 | 17 | 18 | def set(self, data): 19 | self.data = data 20 | 21 | 22 | def compute(self): 23 | spl=[] 24 | coordflag = 0 25 | indexflag = 0 26 | scaleflag = 0 27 | coords = [] 28 | indices = [] 29 | scale=[] 30 | llc = [] 31 | lli = [] 32 | result = [] 33 | ind = [] 34 | length = 0 35 | 36 | for i in range(len(self.data)): 37 | d = self.data[i] 38 | spl = d.split() 39 | 40 | for k in range(len(spl)): 41 | if spl[k] == 'coord' and spl[k+1] == 'Coordinate': 42 | coordflag = 1 43 | 44 | if spl[k] == 'coordIndex': 45 | indexflag = 1 46 | 47 | if spl[k] == 'scale': 48 | scaleflag = 1 49 | 50 | 51 | 52 | if coordflag == 1: 53 | if spl[0]=='}': # we reach the end of 'coords' 54 | coordflag=0 55 | continue 56 | 57 | if spl[0] == 'coord': #this is the first line which we dont 58 | continue #want to parse 59 | 60 | if spl[-1] == ']': #this is the last line where we want 61 | lc = spl[-4:-1] #to get rid of the ']' 62 | else: 63 | lc = spl[-3:] 64 | lc[-1] = lc[-1][:-1] 65 | 66 | llc=[] 67 | for n in range(len(lc)): 68 | 69 | llc.append(float(lc[n])) 70 | coords.append(llc) 71 | 72 | 73 | if indexflag == 1: 74 | testEnd = d.split() 75 | # if testEnd[0]=='texCoord': 76 | # indexflag=0 77 | # continue 78 | 79 | if spl[-1] == ']': #this is the last line where we want 80 | li = spl[-9:-1] #to get rid of the ']' 81 | li[-1] = li[-1]+',' #and add a ',' to the last number 82 | indexflag=0 83 | else: 84 | li = spl[-8:] 85 | 86 | ind.extend(li) 87 | lli = [] 88 | 89 | 90 | if scaleflag == 1: 91 | sc = d.split() 92 | scale.append( float(sc[1]) ) 93 | scale.append( float(sc[2]) ) 94 | scale.append( float(sc[3]) ) 95 | scaleflag = 0 96 | 97 | # make index list. Note that we add -1 as many times as needed 98 | # to each index entry in order to make them all the same length 99 | 100 | lenght=0 # this is the variable that tells us how many -1 we will ad 101 | for n in range(len(ind)): 102 | if ind[n] != '-1,': 103 | lli.append(int(ind[n][:-1])) 104 | else: 105 | lli.reverse() # index list has to be inverted 106 | lli.append(-1) 107 | if len(lli) > length: length = len(lli) 108 | indices.append(lli) 109 | lli = [] 110 | 111 | 112 | 113 | # here we go again over the indices and add the -1 if necessary 114 | for m in range(len(indices)): 115 | if len(indices[m]) < length: 116 | for o in range(length-len(indices[m])): 117 | indices[m].append(-1) 118 | 119 | # apply scale to coords 120 | if len(scale): 121 | coords = numpy.multiply(coords, scale) 122 | 123 | result = [coords]+[indices] 124 | return result 125 | 126 | 127 | def __call__(self): 128 | out=[] 129 | out = self.compute() 130 | return out 131 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/recentFiles.py: -------------------------------------------------------------------------------- 1 | """Impements Recent Files menues""" 2 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/mglutil/util/recentFiles.py,v 1.16 2010/10/05 17:25:40 sargis Exp $ 3 | # 4 | # $Id: recentFiles.py,v 1.16 2010/10/05 17:25:40 sargis Exp $ 5 | import os, pickle 6 | from mglutil.util.packageFilePath import getResourceFolderWithVersion 7 | import tkinter 8 | 9 | class RecentFiles: 10 | """Class to store Recent Files""" 11 | def __init__(self, masterApp, masterMenu, filePath=None, 12 | menuLabel="Open recent", underline=5, index=0): 13 | """Construct recent files categories. If filePath is not provided 14 | mglutil/recent.pkl is used to store and load the data""" 15 | if not filePath: #use "mglutil/recent.pkl" to store the data 16 | filePath = getResourceFolderWithVersion() 17 | if filePath is None: 18 | return 19 | filePath += os.sep + "mglutil" + os.sep + "recent.pkl" 20 | if os.path.exists(filePath): 21 | try: 22 | self.categories = pickle.load(open(filePath)) 23 | except Exception as inst: 24 | #print inst 25 | #print "Couldn't Load Recent Files." 26 | self.categories = {} 27 | else: 28 | self.categories = {} 29 | self.resourceFilePath = filePath 30 | self.checkCategories() 31 | if masterMenu != None: 32 | self.gui(masterMenu, menuLabel, underline=underline, index=index) 33 | else: 34 | self.mainMenu = None 35 | self.masterApp = masterApp 36 | 37 | def checkCategories(self): 38 | """Loops through self.categories to check if recent file still exists. 39 | If not, removes the file from the list""" 40 | for category in list(self.categories.keys()): 41 | newList = [x for x in self.categories[category] if os.path.exists(x[0])] 42 | if len(newList): 43 | self.categories[category] = newList 44 | else: 45 | self.categories.pop(category) 46 | 47 | def add(self, filePath, cmdStr, category="Documents"): 48 | """Add file to self.categories[category] list. 49 | First element in this list is the file. 50 | Second is the command string - cmdStr.""" 51 | if not filePath: 52 | return 53 | if hasattr(self, 'categories') is False: 54 | return 55 | 56 | if category not in self.categories: 57 | self.categories[category] = [] 58 | #self.menuList[category] = Tkinter.Menu(self.mainMenu) 59 | #self.mainMenu.add_cascade(label=category, 60 | # menu=self.menuList[category]) 61 | if os.path.exists(filePath): 62 | filePath = os.path.abspath(filePath) 63 | if [filePath,cmdStr] in self.categories[category]: 64 | index = self.categories[category].index([filePath,cmdStr]) 65 | self.categories[category].pop(index) 66 | if self.mainMenu != None : self.mainMenu.delete(index+1) 67 | if len(self.categories[category]) > 20: 68 | self.categories[category].pop() 69 | #self.menuList[category].delete(10,Tkinter.END) 70 | self.categories[category].insert(0, [filePath,cmdStr]) 71 | if self.mainMenu != None : self.mainMenu.insert(0,'command', label=filePath, 72 | command=self.callback([filePath,cmdStr])) 73 | self.dumpCategories() 74 | 75 | def dumpCategories(self, filePath=None): 76 | """Calls pickle.dump(self.categories, open(filePath,'w'))""" 77 | if not filePath: 78 | filePath = self.resourceFilePath 79 | try: 80 | pickle.dump(self.categories, open(filePath,'w')) 81 | except Exception as inst: 82 | print("Failed to save recent files") 83 | print(inst) 84 | 85 | def gui(self, masterMenu, menuLabel, underline=None, index=0): 86 | self.mainMenu = tkinter.Menu(masterMenu) 87 | masterMenu.insert_cascade(index, label=menuLabel, 88 | menu=self.mainMenu, underline=underline) 89 | self.menuList = {} 90 | for category in self.categories: 91 | # self.menuList[category] = Tkinter.Menu(self.mainMenu) 92 | # self.mainMenu.add_cascade(label=category, 93 | # menu=self.menuList[category]) 94 | for listItem in self.categories[category]: 95 | self.mainMenu.add_command(label=listItem[0], 96 | command=self.callback(listItem)) 97 | 98 | def callback(self, listItem): 99 | def call(listItem=listItem): 100 | masterApp = self.masterApp 101 | eval("masterApp." + listItem[1] + '(' + repr(listItem[0]) +')') 102 | return call 103 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/relpath.py: -------------------------------------------------------------------------------- 1 | """ Author: Alan Ezust 2 | Version: 2.2 3 | Date: October 30, 2004 4 | (relpath.py v1 originally by Cimarron Taylor 5 | from Oreilly/Activestate Python cookbook 2003) 6 | 7 | helper functions for relative paths. 8 | This package includes rel2abs() and abs2rel(), 9 | based on the perl functions from cpan File::Spec 10 | 11 | Version 2.1 fixes/simplifies pathsplit - uses the string split instead of 12 | a very inefficient recursive routine. 13 | Also fixed rel2abs to do a normpath on already absolute paths. 14 | 15 | """ 16 | 17 | import os 18 | import os.path 19 | import re 20 | 21 | # matches http:// and ftp:// and mailto:// 22 | protocolPattern = re.compile(r'^\w+://') 23 | parent = ".." + os.path.sep # use urlparse.urljoin for relative urls 24 | 25 | 26 | def isabs(string): 27 | """ 28 | 29 | @return true if string is an absolute path or protocoladdress 30 | for addresses beginning in http:// or ftp:// or ldap:// - 31 | they are considered "absolute" paths. 32 | """ 33 | if protocolPattern.match(string): return 1 34 | return os.path.isabs(string) 35 | 36 | 37 | def rel2abs(path, base = os.curdir): 38 | """ converts a relative path to an absolute path. 39 | 40 | @param path the path to convert - if already absolute, is returned 41 | normalized 42 | @param base - optional. Defaults to the current location 43 | The base is intelligently concatenated to the given relative path. 44 | @return the relative path of path from base 45 | """ 46 | if isabs(path): return os.path.normpath(path) 47 | retval = os.path.join(base,path) 48 | return os.path.abspath(retval) 49 | 50 | 51 | def commonpath(l1, l2, common=[]): 52 | if len(l1) < 1: return (common, l1, l2) 53 | if len(l2) < 1: return (common, l1, l2) 54 | if l1[0] != l2[0]: return (common, l1, l2) 55 | return commonpath(l1[1:], l2[1:], common+[l1[0]]) 56 | 57 | 58 | def relpath(base, path): 59 | """ returns the relative path from base to path """ 60 | baselist = base.split(os.path.sep) 61 | pathlist = path.split(os.path.sep) 62 | (common,l1,l2) = commonpath(baselist, pathlist) 63 | p = [] 64 | if len(l1) > 0: 65 | p = [ parent * len(l1) ] 66 | p = p + l2 67 | if len(p) is 0: 68 | return "." 69 | return os.path.join( *p ) 70 | 71 | 72 | def abs2rel(path, base = os.curdir): 73 | """ @return a relative path from base to path. 74 | 75 | base can be absolute, or relative to curdir, or defaults 76 | to curdir. 77 | """ 78 | if protocolPattern.match(path): return path 79 | base = rel2abs(base) 80 | return relpath(base, path) 81 | 82 | 83 | if __name__ == "__main__" : 84 | filename = "/home/alan/public_html/oopdocbook/icons/home.png" 85 | path1 = "/home/alan/public_html/oopdocbook" 86 | path2 = "/home/alan/public_html/oopdocbook/" 87 | 88 | rel1 = abs2rel(filename, path1) 89 | rel2 = abs2rel(filename, path2) 90 | assert (rel1 == rel2) 91 | 92 | assert (rel2 == "icons/home.png") 93 | 94 | path3 = "/home/alan/public_html/photos/misc/jewel.png" 95 | path4 = "/home/alan/public_html/oopdocbook/docs/" 96 | relpath = abs2rel(path3, path4) 97 | 98 | expected = os.path.join("..", "..", "photos", "misc", "jewel.png") 99 | assert (relpath == expected) 100 | 101 | print("done") 102 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/repeatPrinter.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | class RepeatPrinter: 4 | """ 5 | The class allows printing repeating messages on the last line of a terminal (Unix only). This can be used to display a counter that does not scroll the terminal 6 | 7 | example: 8 | printer = RepeatPrinter() 9 | printer.prompt('Hello World') 10 | for i in range(20): 11 | printer.update(str(i)) 12 | 13 | thsi code will display 'Hello World' followed by a counter 14 | """ 15 | 16 | def __init__(self): 17 | # use tcup lines to find out how many lines in the terminal 18 | self.nbLines = int(os.popen("tput lines").readlines()[0]) 19 | self.repeatingPosition = None 20 | 21 | 22 | def prompt(self, prompt): 23 | # print a message leading the repeating messages 24 | 25 | #os.system("tput sc") 26 | os.system("tput cup %d 0"%(self.nbLines-1)) 27 | self.repeatingPosition = len(prompt) + 1 28 | print(prompt) 29 | 30 | def update(self, msg): 31 | os.system("tput cup %d %d"%(self.nbLines-2, self.repeatingPosition)) 32 | print(msg) 33 | 34 | 35 | 36 | if __name__ == '__main__': 37 | from time import sleep 38 | 39 | printer = RepeatPrinter() 40 | printer.prompt('Hello World') 41 | 42 | sleep(0.5) 43 | for i in range(20): 44 | printer.update(str(i)) 45 | sleep(0.2) 46 | 47 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/tree.py: -------------------------------------------------------------------------------- 1 | # 2 | # Last modified on Wed Oct 10 15:07:59 PDT 2001 by lindy 3 | # 4 | # $Header: /mnt/raid/services/cvs/python/packages/share1.5/mglutil/util/tree.py,v 1.3 2001/10/10 22:27:01 lindy Exp $ 5 | # 6 | 7 | 8 | class TreeNode: 9 | """Base class of generic tree nodes. 10 | 11 | This class will work all by itself with data being 12 | whatever you want your nodes to be. It also could 13 | be used as the superclass of specific subclasses. 14 | """ 15 | def __init__(self, parent=None, data=None): 16 | self.parent = parent 17 | self.children = [] 18 | if parent: 19 | parent.add_child(self) 20 | if data: 21 | self.data = data 22 | 23 | 24 | def add_child(self, child): 25 | """Add given node to children of self. 26 | 27 | parent.add_child( node) adds node to children of parent. 28 | This is done in the __init__ if parent is given when node 29 | in instanciated (that's the prefered method). 30 | """ 31 | self.children.append(child) 32 | 33 | 34 | def pre_traverse(self, f, *args, **kw): 35 | """Apply f to yourself and then your children recursively 36 | The function f must take the treeNode as it's first argument. 37 | """ 38 | args = list(args) 39 | args[0] = self 40 | a = tuple([f] + args) 41 | 42 | f(*args, **kw) 43 | for c in self.children: 44 | c.pre_traverse(*a, **kw) 45 | 46 | 47 | def post_traverse(self, f, *args, **kw): 48 | """Traverse children with f and args, then visit parent. 49 | The function f must take the treeNode as it's first argument. 50 | """ 51 | args = list(args) 52 | args[0] = self 53 | a = tuple([f] + args) 54 | for c in self.children: 55 | c.post_traverse(*a, **kw) 56 | f(*args, **kw) 57 | 58 | 59 | 60 | 61 | 62 | def get_iterator(self): 63 | """over-ride me to supply an appropriate subclass of TreeIterator""" 64 | raise NotImplementedError 65 | 66 | 67 | 68 | class TreeIterator: 69 | """This iterator class is not finished yet. 70 | """ 71 | def __init__(self, node): 72 | self.iterRoot = node 73 | self.currentNode = None # set by subclass 74 | self.done = None 75 | 76 | 77 | def current(self): 78 | """return the currently-visited node""" 79 | return self.currentNode 80 | 81 | 82 | def done(self): 83 | """Returns false (None) until the traversal is finished""" 84 | return self.done 85 | 86 | 87 | def first(self): 88 | """Reset the currentNode to the initally specified node 89 | """ 90 | self.currentNode = self.iterRoot 91 | 92 | 93 | def __next__(self): 94 | """Move currentNode on to the next item in the traversal. 95 | 96 | Over-ride this method to provide a specific type of traversal 97 | """ 98 | # move on to next item 99 | raise NotImplementedError 100 | 101 | 102 | 103 | 104 | class PostTreeIterator(TreeIterator): 105 | """This iterator class is not finished yet. 106 | """ 107 | def __init__(self, node): 108 | TreeIterator.__init__(self) 109 | self.nodeList = [] 110 | self.iterRoot.post_traverse(self.nodeList.append) 111 | self.currentIx = 0 112 | 113 | 114 | def __next__(self): 115 | self.currentNode = self.nodeList[self.currentIx] 116 | self.currentIx = self.currentIx + 1 117 | if self.currentIx == len(self.nodeList): 118 | self.done = 1 119 | 120 | 121 | 122 | class PreTreeIterator(TreeIterator): 123 | """This iterator class is not finished yet. 124 | """ 125 | def __init__(self, node): 126 | TreeIterator.__init__(self) 127 | self.nodeList = [] 128 | self.iterRoot.pre_traverse(self.nodeList.append) 129 | self.currentIx = 0 130 | 131 | 132 | def __next__(self): 133 | self.currentNode = self.nodeList[self.currentIx] 134 | self.currentIx = self.currentIx + 1 135 | if self.currentIx == len(self.nodeList): 136 | self.done = 1 137 | 138 | -------------------------------------------------------------------------------- /src/external/AutoDockTools/mglutil/util/uniq.py: -------------------------------------------------------------------------------- 1 | ## def uniq(l, func=None): 2 | ## """Return a new list with duplicate items removed.""" 3 | 4 | ## l2 = l[:] # make a copy 5 | ## d = {} 6 | ## def add_to_dict(value,d=d): 7 | ## d[`value`] = value 8 | ## map(add_to_dict,l2) 9 | ## l3 = d.values() 10 | ## if len(l2)==len(l3): return(l2) 11 | ## if func: l3.sort(func) 12 | ## else: l3.sort() 13 | ## return l3 14 | 15 | def uniq(alist): # Fastest order preserving 16 | set = {} 17 | return [set.setdefault(e,e) for e in alist if e not in set] 18 | 19 | def uniq3(alist): # Fastest without order preserving 20 | set = {} 21 | list(map(set.__setitem__, alist, [])) 22 | return list(set.keys()) 23 | 24 | """ 25 | from mglutil.util.uniq import uniq, uniq2, uniq3 26 | import time 27 | a=range(100) 28 | b=range(10) 29 | c=a+b 30 | 31 | t1=time.time() 32 | for i in range(5000): x=uniq(c) 33 | print time.time()-t1 34 | 35 | t1=time.time() 36 | for i in range(5000): x=uniq2(c) 37 | print time.time()-t1 38 | 39 | t1=time.time() 40 | for i in range(5000): x=uniq3(c) 41 | print time.time()-t1 42 | 43 | 44 | >>> 45 | 0.865363121033 46 | 0.463307857513 47 | 0.260641098022 48 | """ 49 | -------------------------------------------------------------------------------- /src/metal_dock/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ -------------------------------------------------------------------------------- /src/metal_dock/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/metal_dock/environment_variables.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import subprocess as sp 4 | 5 | from src.metal_dock.logger import MetalDockLogger 6 | 7 | def find_command_path(command: str): 8 | """ 9 | Function to find the path of a command. 10 | 11 | Args: 12 | command (str): The command to find. 13 | 14 | Returns: 15 | str: The path of the command. 16 | """ 17 | # Try searching in the Conda environment's bin directory 18 | conda_env_bin = os.path.join(sys.prefix, 'bin', command) 19 | if os.path.exists(conda_env_bin): 20 | return conda_env_bin 21 | 22 | try: 23 | if sys.platform.startswith('win'): 24 | # On Windows, use the 'where' command 25 | result = sp.check_output(['where', command], universal_newlines=True) 26 | else: 27 | # On Unix-based systems, use the 'which' command 28 | result = sp.check_output(['which', command], universal_newlines=True) 29 | 30 | # Remove any leading/trailing whitespace and return the path 31 | return result.strip() 32 | except sp.CalledProcessError: 33 | logger = MetalDockLogger() 34 | logger.info(f"Error: The command '{command}' was not found in your system's PATH.") 35 | logger.info(f"Pleae ensure that all paths are set correctly.") 36 | logger.info(f"If paths keep failing, please try to set the absolute path manually in the file '/MetalDock/src/metal_dock/environment_variables.py'.") 37 | sys.exit() 38 | 39 | 40 | ROOT_DIR = os.path.dirname(os.path.abspath(__file__))[:-11] # Project Root 41 | os.environ['ROOT_DIR']=ROOT_DIR 42 | 43 | os.environ['OBABEL']=find_command_path('obabel') 44 | os.environ['PDB2PQR']=find_command_path('pdb2pqr30') 45 | os.environ['MGLTOOLS']=os.path.join(os.environ['ROOT_DIR'],'external','AutoDockTools') 46 | os.environ['PYTHON_3']=find_command_path('python3') 47 | -------------------------------------------------------------------------------- /src/metal_dock/logger.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import logging 3 | from pathlib import Path 4 | 5 | class MetalDockLogger: 6 | _instance = None 7 | _initialized = False 8 | 9 | def __new__(cls): 10 | if cls._instance is None: 11 | cls._instance = super(MetalDockLogger, cls).__new__(cls) 12 | return cls._instance 13 | 14 | def __init__(self): 15 | if not MetalDockLogger._initialized: 16 | self.logger = logging.getLogger('MetalDock') 17 | self.logger.setLevel(logging.INFO) 18 | 19 | # Create formatters 20 | console_formatter = logging.Formatter('%(message)s') 21 | file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 22 | 23 | # Console handler 24 | console_handler = logging.StreamHandler(sys.stdout) 25 | console_handler.setFormatter(console_formatter) 26 | self.logger.addHandler(console_handler) 27 | 28 | # Store handlers for later use 29 | self.handlers = {'console': console_handler} 30 | 31 | MetalDockLogger._initialized = True 32 | 33 | def setup_file_logger(self, log_dir: Path): 34 | """ 35 | Setup file logging based on the method. 36 | 37 | Args: 38 | log_dir (Path): The directory to store the log file. 39 | """ 40 | # Define log file path 41 | log_file_path = log_dir / f'MetalDock.log' 42 | 43 | # Remove existing log file if it exists 44 | if log_file_path.exists(): 45 | log_file_path.unlink() 46 | 47 | # Create file handler 48 | file_handler = logging.FileHandler(log_file_path) 49 | file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 50 | file_handler.setFormatter(file_formatter) 51 | 52 | self.logger.addHandler(file_handler) 53 | self.handlers['file'] = file_handler 54 | 55 | def set_level(self, level: int): 56 | """ 57 | Set logging level. 58 | 59 | Args: 60 | level (int): The logging level. 61 | """ 62 | self.logger.setLevel(level) 63 | 64 | def info(self, msg: str): 65 | """ 66 | Log info message. 67 | 68 | Args: 69 | msg (str): The message to log. 70 | """ 71 | self.logger.info(msg) 72 | 73 | def debug(self, msg: str): 74 | """ 75 | Log debug message. 76 | 77 | Args: 78 | msg (str): The message to log. 79 | """ 80 | self.logger.debug(msg) 81 | 82 | def warning(self, msg: str): 83 | """ 84 | Log warning message. 85 | 86 | Args: 87 | msg (str): The message to log. 88 | """ 89 | self.logger.warning(msg) 90 | 91 | def error(self, msg: str): 92 | """ 93 | Log error message. 94 | 95 | Args: 96 | msg (str): The message to log. 97 | """ 98 | self.logger.error(msg) 99 | 100 | def critical(self, msg: str): 101 | """ 102 | Log critical message. 103 | 104 | Args: 105 | msg (str): The message to log. 106 | """ 107 | self.logger.critical(msg) 108 | -------------------------------------------------------------------------------- /src/metal_dock/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import argparse 4 | 5 | from pathlib import Path 6 | 7 | from src.metal_dock.parser_metal_dock import DockParser, MCParser 8 | from src.metal_dock.protein import Protein 9 | from src.metal_dock.metal_complex import MetalComplex 10 | from src.metal_dock.docking import Docking 11 | from src.metal_dock.monte_carlo import MonteCarloOptimization 12 | from src.metal_dock.logger import MetalDockLogger 13 | 14 | def docking(par: DockParser): 15 | """ 16 | Docking function. 17 | 18 | Args: 19 | par (DockParser): The parser object. 20 | """ 21 | input_dir = Path.cwd() 22 | par.output_dir = input_dir / 'output' 23 | #=== OUTPUT DIRECTORY ===# 24 | par.output_dir.mkdir(exist_ok=True) 25 | 26 | #=== FILE PREPARATION ===# 27 | file_prep_dir = par.output_dir / 'file_prep' 28 | file_prep_dir.mkdir(exist_ok=True) 29 | 30 | #=== PROTEIN INITIALIZATION ===# 31 | # initialize the protein 32 | protein = Protein(par) 33 | protein.create_pdbqt_file() 34 | 35 | #=== METAL COMPLEX INITIALIZATION ===# 36 | metal_complex = MetalComplex(par) 37 | metal_complex.canonicalize_ligand() 38 | 39 | # run the qm engine 40 | metal_complex.qm_engine.run() 41 | 42 | # create the pdbqt file 43 | metal_complex.create_ligand_pdbqt_file() 44 | 45 | #=== DOCKING ===# 46 | docking_dir = par.output_dir / 'docking' 47 | docking_dir.mkdir(exist_ok=True) 48 | 49 | docking = Docking(par, metal_complex, protein) 50 | docking.run() 51 | 52 | results_dir = par.output_dir / 'results' 53 | results_dir.mkdir(exist_ok=True) 54 | 55 | docking.analyze_results() 56 | 57 | def optimize_MC(par: MCParser, input_file: str): 58 | """ 59 | Function to optimize the parameters with the Monte Carlo optimization. 60 | 61 | Args: 62 | par (MCParser): The parser object. 63 | input_file (str): The input file. 64 | """ 65 | input_dir = Path.cwd() 66 | par.input_dir = input_dir 67 | par.output_dir = input_dir / 'output' 68 | #=== OUTPUT DIRECTORY ===# 69 | par.output_dir.mkdir(exist_ok=True) 70 | 71 | optimize_MC = MonteCarloOptimization(par, input_file) 72 | optimize_MC.optimize() 73 | 74 | def main(): 75 | parser = argparse.ArgumentParser(description="Docking of organometallic compounds") 76 | parser.add_argument("-i","--input_file", help="Input file of .ini format specifying all parameters", required=True) 77 | parser.add_argument("-m","--method", choices=['dock', 'mc'], help="Method to use", required=True) 78 | args = parser.parse_args() 79 | 80 | logger = MetalDockLogger() 81 | logger.setup_file_logger(Path.cwd()) 82 | 83 | logger.info('#==============================================================================#') 84 | logger.info("STARTING METALDOCK") 85 | logger.info('#==============================================================================#\n') 86 | 87 | # if input file not found give errror 88 | if not os.path.exists(args.input_file): 89 | logger = MetalDockLogger() 90 | logger.info("Input file not found") 91 | sys.exit() 92 | 93 | if args.method.lower() == 'dock': 94 | par = DockParser(args.input_file) 95 | par.method = 'dock' 96 | docking(par) 97 | elif args.method.lower() == 'mc': 98 | par = MCParser(args.input_file) 99 | par.method = 'mc' 100 | optimize_MC(par, args.input_file) 101 | else: 102 | logger = MetalDockLogger() 103 | logger.info("SPECIFY ONE OF THE TWO OPTIONS FOR MetalDock") 104 | logger.info("(1) dock") 105 | logger.info("(2) mc") 106 | 107 | if __name__== '__main__': 108 | main() 109 | -------------------------------------------------------------------------------- /src/metal_dock/protein.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import sys 4 | import subprocess as sp 5 | from src.metal_dock.logger import MetalDockLogger 6 | 7 | class Protein: 8 | def __init__(self, par): 9 | self.par = par 10 | self.logger = MetalDockLogger() 11 | self.protonate_pdb() 12 | self.clean_protein_pdb() 13 | 14 | def protonate_pdb(self): 15 | """ 16 | Protonate the protein. 17 | """ 18 | if not (self.par.output_dir / 'file_prep' / f'{self.par.name_protein}.pdb').exists(): 19 | input_pdb = self.par.pdb_file 20 | output_pdb_protonated = self.par.output_dir / 'file_prep' / f'{self.par.name_protein}.pdb' 21 | 22 | if self.par.clean_pdb == True: 23 | sp.call(os.environ['PDB2PQR']+f' --noopt --pdb-output {output_pdb_protonated} --with-ph {str(self.par.pH)} --drop-water {input_pdb} {output_pdb_protonated}', shell=True, stdout=sp.PIPE, stderr=sp.PIPE) 24 | else: 25 | sp.call(os.environ['PDB2PQR']+f' --noopt --pdb-output {output_pdb_protonated} --with-ph {str(self.par.pH)} {input_pdb} {output_pdb_protonated}', shell=True, stdout=sp.PIPE, stderr=sp.PIPE) 26 | 27 | def clean_protein_pdb(self): 28 | """ 29 | Remove cofactors or ligands from the pdb file 30 | """ 31 | pdb_input_path = self.par.output_dir / 'file_prep' / f'{self.par.name_protein}.pdb' 32 | pdb_output_path = self.par.output_dir / 'file_prep' / f'clean_{self.par.name_protein}.pdb' 33 | 34 | if self.par.clean_pdb == True: 35 | with open(pdb_input_path, 'r') as fin: 36 | with open(pdb_output_path, 'w') as fout: 37 | for line in fin: 38 | if 'HETATM' not in line: 39 | fout.write(line) 40 | else: 41 | shutil.move(pdb_input_path, pdb_output_path) 42 | 43 | self.pdb_file = pdb_output_path 44 | 45 | def create_pdbqt_file(self): 46 | """ 47 | Create the pdbqt file for the protein. 48 | """ 49 | if not (self.par.output_dir / 'file_prep' / f'clean_{self.par.name_protein}.pdbqt').exists(): 50 | pdb_path = self.par.output_dir / 'file_prep' / f'clean_{self.par.name_protein}.pdb' 51 | pdbqt_path = self.par.output_dir / 'file_prep' / f'clean_{self.par.name_protein}.pdbqt' 52 | prepare_gpf4 = os.path.join(os.environ['MGLTOOLS'], 'prepare_receptor4.py') 53 | command = os.environ['PYTHON_3']+f' {prepare_gpf4} -U nphs -A None -r {pdb_path} -o {pdbqt_path}' 54 | 55 | process = sp.Popen( 56 | command, 57 | shell=True, 58 | stdout=sp.PIPE, 59 | stderr=sp.PIPE, 60 | universal_newlines=True 61 | ) 62 | stdout, stderr = process.communicate() 63 | 64 | if process.returncode != 0: 65 | out_file = self.par.output_dir / 'file_prep' / 'prepare_receptor.out' 66 | with open(out_file, 'w') as fout: 67 | fout.write(stdout) 68 | fout.write(stderr) 69 | self.logger.error('ERROR DURING PREPARATION OF RECEPTOR, SEE /output/file_prep/prepare_receptor.out FOR DETAILS') 70 | self.logger.error('IF PDB FILE IS NOT WRITTEN IN CORRECT PDB FORMAT, PLEASE EDIT MANUALLY') 71 | sys.exit() 72 | else: 73 | self.logger.info('RECEPTOR PDBQT FILE ALREADY EXISTS\n') 74 | -------------------------------------------------------------------------------- /src/metal_dock/xyz2graph.py: -------------------------------------------------------------------------------- 1 | """ 2 | Adapted from https://github.com/zotko/xyz2graph/tree/master 3 | 4 | """ 5 | 6 | import re 7 | from itertools import combinations 8 | from math import sqrt 9 | 10 | import numpy as np 11 | import networkx as nx 12 | 13 | atomic_radii = dict( 14 | Ac=1.88, 15 | Ag=1.59, 16 | Al=1.35, 17 | Am=1.51, 18 | As=1.21, 19 | Au=1.50, 20 | B=0.83, 21 | Ba=1.34, 22 | Be=0.35, 23 | Bi=1.54, 24 | Br=1.21, 25 | C=0.68, 26 | Ca=0.99, 27 | Cd=1.69, 28 | Ce=1.83, 29 | Cl=0.99, 30 | Co=1.33, 31 | Cr=1.35, 32 | Cs=1.67, 33 | Cu=1.52, 34 | D=0.23, 35 | Dy=1.75, 36 | Er=1.73, 37 | Eu=1.99, 38 | F=0.64, 39 | Fe=1.34, 40 | Ga=1.22, 41 | Gd=1.79, 42 | Ge=1.17, 43 | H=0.23, 44 | Hf=1.57, 45 | Hg=1.70, 46 | Ho=1.74, 47 | I=1.40, 48 | In=1.63, 49 | Ir=1.32, 50 | K=1.33, 51 | La=1.87, 52 | Li=0.68, 53 | Lu=1.72, 54 | Mg=1.10, 55 | Mn=1.35, 56 | Mo=1.47, 57 | N=0.68, 58 | Na=0.97, 59 | Nb=1.48, 60 | Nd=1.81, 61 | Ni=1.50, 62 | Np=1.55, 63 | O=0.68, 64 | Os=1.37, 65 | P=1.05, 66 | Pa=1.61, 67 | Pb=1.54, 68 | Pd=1.50, 69 | Pm=1.80, 70 | Po=1.68, 71 | Pr=1.82, 72 | Pt=1.50, 73 | Pu=1.53, 74 | Ra=1.90, 75 | Rb=1.47, 76 | Re=1.35, 77 | Rh=1.45, 78 | Ru=1.40, 79 | S=1.02, 80 | Sb=1.46, 81 | Sc=1.44, 82 | Se=1.22, 83 | Si=1.20, 84 | Sm=1.80, 85 | Sn=1.46, 86 | Sr=1.12, 87 | Ta=1.43, 88 | Tb=1.76, 89 | Tc=1.35, 90 | Te=1.47, 91 | Th=1.79, 92 | Ti=1.47, 93 | Tl=1.55, 94 | Tm=1.72, 95 | U=1.58, 96 | V=1.33, 97 | W=1.37, 98 | Y=1.78, 99 | Yb=1.94, 100 | Zn=1.45, 101 | Zr=1.56, 102 | ) 103 | 104 | 105 | class MolGraph: 106 | """Represents a molecular graph.""" 107 | 108 | __slots__ = [ 109 | "elements", 110 | "x", 111 | "y", 112 | "z", 113 | "adj_list", 114 | "atomic_radii", 115 | "bond_lengths", 116 | "adj_matrix", 117 | ] 118 | 119 | def __init__(self): 120 | self.elements = [] 121 | self.x = [] 122 | self.y = [] 123 | self.z = [] 124 | self.adj_list = {} 125 | self.atomic_radii = [] 126 | self.bond_lengths = {} 127 | self.adj_matrix = None 128 | 129 | def read_xyz(self, file_path: str) -> None: 130 | """Reads an XYZ file, searches for elements and their cartesian coordinates 131 | and adds them to corresponding arrays.""" 132 | with open(file_path) as file: 133 | for _ in range(2): 134 | next(file) 135 | for line in file: 136 | element, x, y, z = line.strip().split()[:4] 137 | self.elements.append(element) 138 | self.x.append(float(x)) 139 | self.y.append(float(y)) 140 | self.z.append(float(z)) 141 | self.atomic_radii = [atomic_radii[element] for element in self.elements] 142 | self._generate_adjacency_list() 143 | 144 | def _generate_adjacency_list(self): 145 | """Generates an adjacency list from atomic cartesian coordinates.""" 146 | 147 | node_ids = range(len(self.elements)) 148 | xyz = np.stack((self.x, self.y, self.z), axis=-1) 149 | distances = xyz[:, np.newaxis, :] - xyz 150 | distances = np.sqrt(np.einsum("ijk,ijk->ij", distances, distances)) 151 | 152 | atomic_radii = np.array(self.atomic_radii) 153 | distance_bond = (atomic_radii[:, np.newaxis] + atomic_radii) * 1.4 154 | 155 | adj_matrix = np.logical_and(0.1 < distances, distance_bond > distances).astype( 156 | int 157 | ) 158 | 159 | for i, j in zip(*np.nonzero(adj_matrix)): 160 | self.adj_list.setdefault(i, set()).add(j) 161 | self.adj_list.setdefault(j, set()).add(i) 162 | self.bond_lengths[frozenset([i, j])] = round(distance_bond[i, j], 5) 163 | 164 | self.adj_matrix = adj_matrix 165 | 166 | def edges(self): 167 | """Creates an iterator with all graph edges.""" 168 | edges = set() 169 | for node, neighbours in self.adj_list.items(): 170 | for neighbour in neighbours: 171 | edge = frozenset([node, neighbour]) 172 | if edge in edges: 173 | continue 174 | edges.add(edge) 175 | yield node, neighbour 176 | 177 | def __len__(self): 178 | return len(self.elements) 179 | 180 | def __getitem__(self, position): 181 | return self.elements[position], ( 182 | self.x[position], 183 | self.y[position], 184 | self.z[position], 185 | ) 186 | 187 | def to_networkx_graph(graph: MolGraph) -> nx.Graph: 188 | """Creates a NetworkX graph. 189 | Atomic elements and coordinates are added to the graph as node attributes 'element' and 'xyz" respectively. 190 | Bond lengths are added to the graph as edge attribute 'length''""" 191 | G = nx.Graph(graph.adj_list) 192 | node_attrs = { 193 | num: {"element": element, "xyz": xyz} 194 | for num, (element, xyz) in enumerate(graph) 195 | } 196 | nx.set_node_attributes(G, node_attrs) 197 | edge_attrs = { 198 | edge: {"length": length} for edge, length in graph.bond_lengths.items() 199 | } 200 | nx.set_edge_attributes(G, edge_attrs) 201 | return G --------------------------------------------------------------------------------