Skip to content

Commit

Permalink
Merge pull request #402 from ExcitedStates/cvxpy-reduce-main
Browse files Browse the repository at this point in the history
Cvxpy reduce main
  • Loading branch information
dhogan-io committed Feb 14, 2024
2 parents ef2d154 + dbb7ca2 commit b79134e
Show file tree
Hide file tree
Showing 16 changed files with 182 additions and 723 deletions.
49 changes: 6 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,59 +14,29 @@ If you use this software, please cite:
- [Keedy, D. A., Fraser, J. S. & van den Bedem, H. Exposing Hidden Alternative Backbone Conformations in X-ray Crystallography Using qFit. PLoS Comput. Biol. 11, e1004507 (2015)](https://dx.doi.org/10.1371/journal.pcbi.1004507)


## Installation (conda recommended)

We recommend using the _conda_ package manager to install _qFit_.
## Installation

You will need the following tools:

* git
* _conda_ package manager (which you can get by installing [Miniconda3](https://docs.conda.io/en/latest/miniconda.html))
* pip

Once these are installed, you can:

1. Create a new conda env & activate it
```bash
conda create --name qfit "python>=3.9"
conda activate qfit
```

1. Install dependencies
```bash
conda install -c anaconda mkl numpy=1.22
conda install -c anaconda -c ibmdecisionoptimization \
cvxopt cplex
pip install -r requirements.txt
```
For some of the post analysis scripts, you will also need sklean
conda install -c anaconda scikit-learn

1. Clone the latest release of the qFit source, and install to your conda env
1. Clone the latest release of the qFit source and install it using pip
```bash
git clone -b main https://github.com/ExcitedStates/qfit-3.0.git
git clone https://github.com/ExcitedStates/qfit-3.0.git
cd qfit-3.0
pip install .
```

1. You're now ready to run qFit programs! See [usage examples](#sec:usage-examples) below for some examples.

### M1 Macs

Unfortunately, the Anaconda repos don't contain 'osx-arm64' binaries for IBM's CPLEX and Intel's mkl.
We don't currently have plans to switch to a different MIQP solver (e.g. Gurobi).

As a workaround, you'll have to force conda to install the 'osx-64' binaries for everything (x86_64).
macOS's Rosetta 2 translation will handle the Intel→AppleSilicon translation.

Instead of the first step in the above Installation section, use this:

1. Create a new conda env & activate it
```bash
CONDA_SUBDIR=osx-64 conda create --name qfit "python>=3.9"
conda activate qfit; conda env config vars set CONDA_SUBDIR=osx-64; conda deactivate
conda activate qfit
```

then follow the rest of the instructions.

### Advanced

Expand All @@ -75,15 +45,10 @@ If you prefer to manage your environments using other methods, qFit has the foll
* [Python 3.6+](https://python.org)
* [numpy](https://numpy.org)
* [scipy](https://scipy.org)
* [cvxopt](https://cvxopt.org)
* [IBM ILOG CPLEX Optimization Studio (Community Edition)](https://www.ibm.com/products/ilog-cplex-optimization-studio)

Installation instructions using `pip` can be found in the `docs` folder.
* [cvxpy](https://www.cvxpy.org)

Once dependencies are installed, you can clone the qFit source, and install to your env as above.

(Note: `python setup.py install` will only work if numpy has _already_ been installed.)


## Contributing

Expand Down Expand Up @@ -167,5 +132,3 @@ Gohlke. See file header.

The `Xpleo` software and `LoopTK` package have been major inspirations for the inverse kinematics
functionality.

[1]: https://www-01.ibm.com/software/websphere/products/optimization/cplex-studio-community-edition/ "IBM website"
22 changes: 1 addition & 21 deletions docs/aws_deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,11 @@

# Tested on Amazon Linux 2, but should work on most RPM-based Linux distros

# install Anaconda RPM GPG keys
sudo rpm --import https://repo.anaconda.com/pkgs/misc/gpgkeys/anaconda.asc

# add Anaconda repository
cat <<EOF | sudo tee /etc/yum.repos.d/conda.repo
[conda]
name=Conda
baseurl=https://repo.anaconda.com/pkgs/misc/rpmrepo/conda
enabled=1
gpgcheck=1
gpgkey=https://repo.anaconda.com/pkgs/misc/gpgkeys/anaconda.asc
EOF

sudo yum -y install conda
sudo yum -y install git gcc

source /opt/conda/etc/profile.d/conda.sh
conda create -y --name qfit
conda activate qfit

conda install -y -c anaconda mkl
conda install -y -c anaconda -c ibmdecisionoptimization cvxopt cplex

git clone https://github.com/ExcitedStates/qfit-3.0.git
cd qfit-3.0/
pip install -r requirements.txt

# Optionally, uncomment the following line to set a specific version of qFit
#git checkout v3.1.2
Expand Down
18 changes: 0 additions & 18 deletions docs/pip_install.md

This file was deleted.

6 changes: 2 additions & 4 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ dependencies:
- libblas[build=*mkl]
- numpy>=1.20,<2
- scipy>=1.0
- cvxpy
- pyscipopt
- pandas>=1.2
- pyparsing>=2.2.0
- cvxopt
- ibmdecisionoptimization::cplex
- osqp
- pip:
- "git+https://github.com/osqp/miosqp.git@ac672338b0593d865dd15b7a76434f25e24244a9#egg=miosqp"
- tqdm
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ requires = [
"wheel", # PEP 508 specifications.
"setuptools_scm",
"numpy>=1.20,<2",
"cvxpy",
"pyscipopt",
]
5 changes: 5 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
numpy
cvxpy
pyscipopt
scipy
scikit-learn
78 changes: 41 additions & 37 deletions scripts/post/calc_rscc.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,64 +8,68 @@
from qfit.volume import XMap
from qfit.validator import Validator

'''
"""
This script will calculate the RSCC of a ligand (or any residue) defined by their ligand name (--ligand) or residue number and chain id (--resi_chain).
It will only work on mtz maps with 2FOFCWT,PH2FOFCWT.
To run:
calc_rscc.py PDB_FILE.pdb MTZ_FILE.mtz --ligand AR6 --pdb PDB_NAME --directory /path/for/output/csv/file
'''
"""


def build_argparser():
p = ArgumentParser(description=__doc__)
p.add_argument("structure", type=str, help="PDB-file containing structure.")
p.add_argument("map", type=str, help="Map.")
p.add_argument("--ligand", type=str, help="name of ligand for RSCC to be calculated on")
p.add_argument("--residue", type=str, help="Chain_ID, Residue_ID for RSCC to be calculated on")
p.add_argument(
"--ligand", type=str, help="name of ligand for RSCC to be calculated on"
)
p.add_argument(
"--residue", type=str, help="Chain_ID, Residue_ID for RSCC to be calculated on"
)
p.add_argument("--pdb", type=str, help="name of PDB")
p.add_argument("--directory", type=str, help="Where to save RSCC info")
return p


def main():
p = build_argparser()
options = p.parse_args()
# Load structure and prepare it
structure = Structure.fromfile(options.structure)
if options.ligand is not None:
ligand = structure.extract("resn", options.ligand, "==")
elif options.residue is not None:
chainid, resi = options.residue.split(",")
ligand = structure.extract(f"resi {resi} and chain {chainid}")
else:
print('Please provide ligand name or residue ID and chain ID')
p = build_argparser()
options = p.parse_args()
# Load structure and prepare it
structure = Structure.fromfile(options.structure)
if options.ligand is not None:
ligand = structure.extract("resn", options.ligand, "==")
elif options.residue is not None:
chainid, resi = options.residue.split(",")
ligand = structure.extract(f"resi {resi} and chain {chainid}")
else:
print("Please provide ligand name or residue ID and chain ID")

# Load and process the electron density map:
xmap = XMap.fromfile(options.map, label="2FOFCWT,PH2FOFCWT")
scaler = MapScaler(xmap)
xmap = xmap.canonical_unit_cell()
footprint = ligand
scaler.scale(footprint, radius=1.5)

# Load and process the electron density map:
xmap = XMap.fromfile(
options.map, label='2FOFCWT,PH2FOFCWT'
)
scaler = MapScaler(xmap)
xmap = xmap.canonical_unit_cell()
footprint = ligand
scaler.scale(footprint, radius=1.5)
xmap = xmap.extract(ligand.coor, padding=8)

xmap = xmap.extract(ligand.coor, padding=8)
# Now that the conformers have been generated, the resulting
# # conformations should be examined via GoodnessOfFit:
validator = Validator(xmap, xmap.resolution, options.directory)
rscc = validator.rscc(ligand)
print(rscc)

# Now that the conformers have been generated, the resulting
# # conformations should be examined via GoodnessOfFit:
validator = Validator(xmap, xmap.resolution, options.directory)
rscc = validator.rscc(ligand)
print(rscc)
csv_filename = f"{options.pdb}_rscc.csv"

csv_filename = f"{options.pdb}_rscc.csv"
# Write to CSV
with open(csv_filename, "w", newline="") as csvfile:
writer = csv.writer(csvfile)
# Write the header
writer.writerow(["PDB", "RSCC"])
# Write the data
writer.writerow([options.pdb, rscc])

# Write to CSV
with open(csv_filename, 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
# Write the header
writer.writerow(["PDB", "RSCC"])
# Write the data
writer.writerow([options.pdb, rscc])

if __name__ == "__main__":
main()
9 changes: 4 additions & 5 deletions scripts/post/find_close_residues.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
from qfit.structure.rotamers import ROTAMERS



def parse_args():
p = argparse.ArgumentParser(description=__doc__)
p.add_argument("structure", type=str, help="PDB-file containing structure.")
Expand Down Expand Up @@ -69,11 +68,11 @@ def main():
close_res.loc[n, "res_id"] = residue_id
close_res.loc[n, "chain"] = chain
n += 1
close_res.to_csv(pdb_name + "_" + args.ligand + "_" +str(args.dist) + "_closeres.csv",
index=False,
)
close_res.to_csv(
pdb_name + "_" + args.ligand + "_" + str(args.dist) + "_closeres.csv",
index=False,
)


if __name__ == "__main__":
main()

3 changes: 2 additions & 1 deletion scripts/post/lig_occ.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ def get_occ(structure, ligand, pdb):
)
)
occ = pd.DataFrame(
lig, columns=["PDB", "ligand_name", "chain", "min_occ", "average_b", "num_altloc"]
lig,
columns=["PDB", "ligand_name", "chain", "min_occ", "average_b", "num_altloc"],
)
occ.to_csv(pdb + "_ligand_occupancy.csv", index=False)

Expand Down
6 changes: 2 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ def main():
install_requires = [
"numpy>=1.20,<2",
"scipy>=1.0",
"cvxpy",
"pyscipopt",
"pandas>=1.2",
"pyparsing>=2.2.0",
"tqdm>=4.0.0",
Expand All @@ -44,10 +46,6 @@ def main():
ext_modules=ext_modules,
setup_requires=setup_requires,
install_requires=install_requires,
extra_dependencies={
"cplex": ["cvxopt", "cplex"],
"osqp": ["osqp", "miosqp @ git+https://github.com/osqp/miosqp.git@ac672338b0593d865dd15b7a76434f25e24244a9#egg=miosqp"],
},
zip_safe=False,
python_requires=">=3.9",
entry_points={
Expand Down
Loading

0 comments on commit b79134e

Please sign in to comment.